共计 2676 个字符,预计需要花费 7 分钟才能阅读完成。
大概会用一个系列,讲一下面试过程中经常会问的一些问题,以及我觉得应该可以怎么回答。
当然,我的回答也并不是标准答案,只是我自己的一些理解,也欢迎其他人发表自己的想法。
作为本系列的第一篇文章,就先讲讲被问的最多的 js 继承问题,但是应该不会写原型链相关的东西,
先列举一个最简单的问题:
写一个 inherit(superClass, subClass) 方法,实现 subClass 继承 superClass
题目隐含的内容
继承有哪些特征,如何检测一个继承是否成功?
子类可以使用父类的方法和属性
子类可以自定义方法和属性,但应该不影响父类和其他继承同一个父类的子类
子类的原型链上可以找到父类(子类的__proto__应指向父类)
子类的实例可以通过 foo instanceof superClass 测试
常见的解法
es5
function inherit(p, s) {
s.prototype = Object.create(p.prototype, {
constructor: {
value: s,
enumerable: false,
writebale: true,
configurable: true
}
})
Object.setPrototypeOf ? Object.setPrototypeOf(s, p) : s.__proto__ = p
}
es4
function inherit(p, s) {
var f = new Function ()
f.prototype = new p()
var r = new f()
s.prototype = r
s.prototype.constructor = s
s.__proto__ = p
f = null
r = null
}
引申的问题:
Object.create 是什么?怎么使用?
Object.create(proto, [propertiesObject])
Object.create 提供了一个创建对象的方法,使用现有的对象作为新创建对象的__proto__,同时可以传入添加到新对象的可枚举属性, 这些属性可以对应到 Object.defineProperties 的第二个参数中。
返回值为所创建的新对象.
例如:
s.prototype = Object.create(f.prototype, {
constructor: {
value: s,
enumberable: false,
writealble: true,
configurale: true
}
})
Object.defineProperties 是什么?怎么使用?可以列举一个 Object.definProperties 的实际应用吗?
Object.defineProperties 可以直接在一个对象上定义或修改属性,并返回该对象。
例如:
target = Object.defineProperties(target, props)
本质上 Object.defineProperties 是对 Object.defineProperty 的集中调用,可以理解为是 Object.definePeropety 的复数版。
Object.defineProperty 的使用方法为:
target = Object.defineProperty(target, prop, descriptor)
所以本质上 Object.defineProperties 就是如下代码:
Object.keys(props).forEach(function (prop) {
let descriptor = props[prop]
Object.defineProperty(target, prop, descriptor)
})
其中 descriptor 的可选值有以下集中:
configurable: 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
enumerable: 当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。
value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
writable: 当且仅当该属性的 writable 为 true 时,value 才能被赋值运算符改变。默认为 false。
get: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
set: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。
如果一个 descriptor 不具有 value, writebale, get 和 set 任意一个关键字,那么将会被认为是一个数据描述符。如果一个描述符同时具有 (value 或 writbale) 和(get 或 set),将会产生一个异常.
继承多个父类怎么做?
继承多个父类的话,可以使用 Object.assign 方法。例如:
targe = Object.assign({}, superClassA, superClassB, …)
但是继承多个父类的话,子类就不能通过 son instanceof superClass 这样的验证了.
Object.assign 是什么?怎么用?用的时候有哪些需要注意?
Object.assign 方法用于将所有可枚举属性从一个或多个源对象复制到目标对象,并返回目标对象,例如:
target = Object.assign(target, source)
如果具有同名属性,那么在后面对象中的属性,将会覆盖目标对象中的属性。
需要注意以下几点:
继承属性和不可枚举属性是不能拷贝的。
原始类型会被包装为对象,null, undefined 会被忽略,并且只有字符串的包装对象才可能有自身可枚举的属性.
可以拷贝 symbol 类型的属性
Object.assign 会调用 setter 和 getter 吗?调用的是哪里的 setter 和 getter ?
Object.assign 会调用源对象的 getter,并把源对象的 getter 的返回值当做新对象的该属性的值。setter 则是会直接加在新创建的对象中,而不会沿用源对象的 setter.
Object.getOwnPropertyDescriptor 是什么?主要用来做什么?
Object.getOwnPropertyDescriptor 返回直到对象上一个自有属性对应的描述符,例如:
Object.getOwnPropertyDescriptor(obj, prop)