更简单的原型语法和原型语法的动态性

更简单的原型语法 为减少不必要的输出,也从视觉上更好的封装原型的功能,用一个包含所有属性和方法的对象字面量来重写整个原型对象:

  function Person() {
   }

   Person.prototype = {
       name : "Hongbin",
       age : 21,
       sex : true,
       sayHello : function () {
           console.log("Hello "+this.name);
       }
   };

存在问题:上面相当于重写了默认的Person.prototype,prototype中的constructor属性也随之改变,不在指向Person。此时instanceof操作符还能返回正确的结果,但通过constructor已经无法确定对象的类型了:

    var person1 = new Person();

    console.log(person1 instanceof Person);//true
    console.log(person1.constructor == Person);//false
    console.log(person1.constructor == Object);//true

如果constructor指向整的很重要,可以手动设置值

    Person.prototype = {
        constructor : Person,
        name : "Hongbin",
        age : 21,
        sex : true,
        sayHello : function () {
            console.log("Hello "+this.name);
        }
    };

    var person2 = new Person();
    console.log(person2.constructor == Person);//true

但以这种方式设置constructor的属性,导致constructor的[[Enumerable]]值变成了true,默认情况下值为false,如果使用的兼容ECMAScript5的JavaScript引擎,可以用Object.defineProperty()方法设置constructor属性

    Object.defineProperty(Person.prototype,'constructor',{
        value:Person,
        enumerable:false
    });
    // console.log(Object.getOwnPropertyDescriptors(Person.prototype));//constructor: {writable: true, enumerable: false, configurable: true, value: ƒ}

到此解决constructor指向因重置prototype属性而产生变化问题

原型链的动态性:原型查找是一次搜索行为,因此我们对原型对象做的任何操作都能立刻反映到实例上–即使先创建了实例后修改原型也是如此:
在设置prototype.name为一个新的值之前打印的实例属性也发生变化
在这里插入图片描述
下图中,我们可以看到在constructor没有设置的时候创建的person1并没有任何改变,甚至constructor依旧没有指向Person,是因为它定义在constructor指向Person之前,
在这里插入图片描述
我们将person2也放到constructor指向Person之前定义发现
在这里插入图片描述
person2也出现了和person1一样的抓概况,对比一下
在这里插入图片描述
person2又恢复正常,
通过person1和person2对比我们发现:

重写的原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系;它们引用的仍是最初的原型

//更简单的原型语法 为减少不必要的输出,也从视觉上更好的封装原型的功能,用一个包含所有属性和方法的对象字面量来重写整个原型对象:
    function Person() {
    }

    Person.prototype = {
        name : "Hongbin",
        age : 21,
        sex : true,
        sayHello : function () {
            console.log("Hello "+this.name);
        }
    };
    //问题:上面相当于重写了默认的Person.prototype,prototype中的constructor属性也随之改变,不在指向Person。此时instanceof操作符还能返回正确的结果,但通过constructor已经无法确定对象的类型了:
    var person1 = new Person();

    console.log(person1 instanceof Person);//true
    console.log(person1.constructor == Person);//false
    console.log(person1.constructor == Object);//true
    //如果constructor指向整的很重要,可以手动设置值
    Person.prototype = {
        constructor : Person,
        name : "Hongbin",
        age : 21,
        sex : true,
        sayHello : function () {
            console.log("Hello "+this.name);
        }
    };

    var person2 = new Person();
    console.log(person2.constructor == Person);//true
    //但以这种方式设置constructor的属性,导致constructor的[[Enumerable]]值变成了true,默认情况下值为false,如果使用的兼容ECMAScript5的JavaScript引擎,可以用Object.defineProperty()方法设置constructor属性
    Object.defineProperty(Person.prototype,'constructor',{
        value:Person,
        enumerable:false
    });
    // console.log(Object.getOwnPropertyDescriptors(Person.prototype));//constructor: {writable: true, enumerable: false, configurable: true, value: ƒ}
    //到此解决constructor指向因重置prototype属性而产生变化问题

    //原型链的动态性:原型查找是一次搜索行为,因此我们对原型对象做的任何操作都能立刻反映到实例上--即使先创建了实例后修改原型也是如此:
    console.log(person2);
    Person.prototype.name = "new name!";
    console.log(person2);//new name!

    console.log(person1);//Hongbin
    console.log(person1.constructor == Person);//false
    //person1并没有改变,constructor也是如此,是因为它定义在constructor指向Person之前

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值