学习的过程不在于死记硬背,而在于怎么去理解它
观察下面的代码和打印的信息
我们可以得出以下结论
每一个对象都有__proto__
属性obj.__proto__.constructor
指向构造函数, 下图中的是指向Object
这个祖先函数
function Fater(name, age) {
this.name = name
this.age = age
}
Fater.prototype.say = function() {
}
let obj = {}
console.log(obj);
下面代码和打印结果
我们是将对象的 obj.__proto__地址赋值成了 Fater.prototype,也就是继承了 Fater.prototype.say 这个方法。
obj 也指向了 Fater这个构造函数的对象
这里我们没有继承Fater函数里面的属性,而是它原型链上的属性
接下来看最后一步
function Fater(name, age) {
this.name = name
this.age = age
}
Fater.prototype.say = function() {
}
let obj = {}
obj.__proto__ = Fater.prototype
console.log('obj', obj);
tip: 观察仔细的话,会有这样的一个疑问
obj.__proto__.constructor
=== Object 函数的
obj.__proto__ = Fater.prototype
改变了指向之后会obj.__proto__.constructor
=== Fater函数
可以这样理解的
obj.__proto__.constructor
=== Fater.prototype.constructor
这样就很好理解了
必须说 let p = new Fater()
我们 new出来的 p 其实就是 上面代码的 obj 对象,但是这个对象还差一点东西
没有继承构造函数上的属性,只是继承了原型链上的属性。
我们利用Function.call() 来实现
下面图打印的 obj 就是我们 new 出来的对象了
function Fater(name, age) {
this.name = name
this.age = age
}
Fater.prototype.say = function() {
}
let obj = {}
obj.__proto__ = Fater.prototype
Fater.call(obj, 'zs', 18)
console.log('obj', obj);
Fater.call(obj, 'zs', 18)
这一步究竟发生了什么?
会将 Fater 上的 name , age 属性指向 obj 这个对象上面来
Fater.call(obj === {} , 'zs', 18)
function Fater(name, age) {
obj.name = name
obj.age = age
}
做事情要去了解本质才行
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)