ps: 这些题目都是在网上找的,附上自己的解释,若有不对的地方,还望大家指正。谢谢大家了。
所有prototype 链的顶端都是 Object.prototype!!!
1. 问题: f 是否有 a b c方法
var F = function () { };
Object.prototype.a = function () { console.log('a') };
F.prototype.b = function () { console.log('b') };
Function.prototype.c = function () { console.log('c') };
var f = new F();
f.a(), f.b(); // b 是它直接原型链上面的方法, a是它原型链顶端 Object.prototype 上面的方法, c 是Function.prototype上面的方法,和它没有任何关系
console.log(f.constructor.b === F.prototype.b); // f.constrcutor 是 F, F.b 因为没有这个b属性,所以去它的原型链Function.prototype 去找,Function.prototype 上面没有发现b,所 结果: false
console.log(f.constructor.prototype.b === F.prototype.b); // f.constructor 是 F, F.prototype.b === F.prototype.b 一样的 结果: true
// f.constructor.c === Function.prototype.c; // F是一个构造函数, F的直接prototype 是 Function.prototype, 所以这里的c也是拿的Function.prototype.c, 结果: true
console.log(f.constructor.a === Object.prototype.a); // f.constrcutor 是 F, F的直接prototype 链是 Function.prototype, 但是Function.prototype 没有这个a属性,于是继续向上查找,这里查找到了prototype链的顶端: Object.prototype, 然后 Object.prototype 上面有a属性,所以这里拿的就是 Object.prototype 上面的a属性, 结果: true
// !!! 需要注意: F.b F没有这个属性,只是会沿着 [[Prototoye]] 链去找,也就是 F.__ proto__ __ 指向的prototype, F.__ proto __ === Function.prototype, 而不是自己去F.prototype 上面去找,大家一定要记住了
console.log(F.constructor.__proto__ === Function.prototype, Function.prototype.__proto__ === Object.prototype); //结果: true 原因的话,大家可以参考我上面的解释
2.
function A() { }
function B(a) {
// let this = {};
// this.a = undefined 因为没有传a进来,因为它自己存在a属性,发生了屏蔽,不会去prototype上面去找
this.a = a;
// return this;
}
function C(a) {
// let this = {};
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a); // 1
console.log(new B().a); // undefined 参考B 里面我写的解释。
console.log(new C(2).a); // 2
3.
var F = function () { }; // F.prototype.__proto__ === Function.prototype
Object.prototype.a = function () {
console.log("a()");
};
Function.prototype.b = function () {
console.log("b()");
};
var f = new F();
F.a(); // a()
F.b(); // b()
f.a(); // a()
f.b(); // 报错 f 是一个对象, f.__proto__ === F.prototype, F.prototype.__proto__ === Object.prototype, 完全不关 Function.prototype 什么事情,Object.prototype上面并没有b方法,所以报错了
4.
// 考点: 属性屏蔽,原始值与引用值
function A() {
this.name = 'a'
this.color = ['green', 'yellow']
}
function B() {
}
B.prototype = new A(); // {name: a, color: []}
var b1 = new B()
var b2 = new B()
b1.name = 'change'; // 因为它自己并没有这个属性,它改的是它的prototype上面的,改了之后,这是一个原始值,发生屏蔽行为,自己把这个属性偷了
b1.color.push('black') // 引用值,首先,b1 是根本没有color这个属性的,它之所以能够访问 b1.color,完全是因为 它的prototype上面有这个属性,所以,它是直接返回了它prototype上面的值,color是prototype上面的一个引用值,它这里保存的是color在prototype里面的地址,b1 对这个color进行修改,prototype里面也一起改了
console.log(b1); // B {name: 'change'} 修改了,发生了屏蔽
console.log(b2); // B {}; b2 上面没有任何属性,全是prototype 上面的,
console.log(b1.name); // change
console.log(b2.name); // a
console.log(b1.color); // [g, y, b]
console.log(b2.color); // [g, y, b] b2 也没有color这个属性,沿着prototype上面的去找,prototype上面的color已经是 [g, y, b]了