代码题
function Foo() {
Foo.a = function() {
console.log(1)
}
this.a = function() {
console.log(2)
}
}
Foo.prototype.a = function() {
console.log(3)
}
Foo.a = function() {
console.log(4)
}
Foo.a(); // 4
let obj = new Foo();
obj.a(); // 2
Foo.a(); // 1
带着一些疑惑来详细拆解这道题:
function Foo() {
//...
}
let obj = new Foo()
new Foo()会创建一个新对象(这里指obj),这个新对象的内部链接[[prototype]]关联的是Foo.prototype对象。
然后打印obj可以看到该对象上目前有两个a方法:1. Foo内部属性方法; 2. 原型方法。
console.log(obj)
obj.a();
当调用obj.a()方法时,第一步先检查对象本身是否有这个属性,有,就使用它,没有,再使用对象的[[Prototype]]链,找到a方法进行调用。
此时obj.a()找到了通过this赋值给本身的a方法,输出为2。
Foo.a();
代码执行到此,Foo已经经过了new操作,重新绑定了全局Foo上的a方法,所以此时输出为1。
参见(重点!!!)
文章写的都很详细且需精读N遍。
- 木易杨前端进阶第100题
- 属性的 getter 和 setter
- F.prototype
- 原生的原型
- 你不知道的javascript上卷