js原型链题目

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]了
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
闭包是指在一个函数内部定义的函数可以访问外部函数的变量和参数,即使外部函数已经执行结束。闭包形成一个封闭的作用域,保留了外部函数的变量和环境。这种特性使得闭包可以解决诸如变量私有化、保存变量状态等问。 闭包的应用场景有很多,例如在异步编程中,可以使用闭包来保持状态,避免变量提升导致的错误;在模块化开发中,可以使用闭包来实现私有变量和方法的封装。但闭包也有一些注意事项,比如会占用内存,造成内存泄漏;还可能导致变量无法被垃圾回收,影响性能。 原型链是JavaScript中实现继承的机制。每个JavaScript对象都有一个内置的属性__proto__指向它的原型对象,原型对象又有自己的__proto__,形成了原型链。当访问对象的属性或方法时,会先在对象本身查找,如果找不到则沿着原型链向上查找,直到找到或者到达原型链的末尾(即null)。 原型链的好处是可以节省内存,将公共的属性和方法定义在原型对象中,所有实例对象共享这些属性和方法;还可以实现继承,子类对象的原型对象可以指向父类对象,从而共享父类的属性和方法。 原型链的缺点是只能继承父类的实例属性和方法,不能继承构造函数中的私有属性和方法;还有可能出现多个子类实例共享同一个父类实例的情况,导致数据共享的问。 为了解决原型链继承的缺点,ES6引入了class关键字,可以更方便地实现面向对象编程,并且支持super关键字调用父类的方法。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值