• 《深入理解JavaScript》—— 对象与继承(第2层)


    导读:两个对象间的原型关系类似继承:每个对象都可以把另一个对象作为它的原型,并继承原型的所有属性。对象通过内部属性[[prototype]]指定它的原型。每隔对象都有这个属性,而它也可以是null。通过[[prototype]]属性连接成的原型成为原型链。

    (1) 继承

    var proto = {
        describe : function () {
            return 'name : ' + this.name;
        }
    };
    var obj = {
        __proto__ : proto,
        name : 'obj'
    };
    console.log(obj.describe); // function()

    obj继承了describe。你可以访问这个属性,就像对象本身拥有该属性一样。

    当你通过obj访问属性时,JavaScript首先从本对象中查找,接着是它的原型,以及原型的原型,以此类推。原型链的行为好像是一个单独的对象。当你调用一个方法时,容易出错是因为this的值总是开始查找方法时所在的那个对象,而不是找到方法时所在的对象。

    在describe()中,this是obj,它允许访问obj.name。

    (2) 覆写

    在一个原型链中,一个对象的属性可以覆写“之后”对象的相同键的属性:前者的属性最先被找到。它隐藏了后者的属性,这样后者的属性就不能被访问了。

    obj.describe = function () {
        return 'overridden';
    };
    console.log(obj.describe());  // overridden

    (3) 通过原型在对象间共享数据

    原型对于对象间数据共享十分有用:多个对象可以有相同的原型,这个原型持有所有的共享属性。例如:

    var PersonData = {
        describe : function () {
            return 'name : ' + this.name;
        }
    };
    var Alice = {
        name : 'Alice',
        __proto__ : PersonData
    };
    var Bob = {
        name : 'Bob',
        __proto__ : PersonData
    };
    console.log(Alice.describe());  // name : Alice
    console.log(Bob.describe());  // name : Bob

    (4) 获取和设置原型

    ① 使用给定prototype创建新对象

    调用方法: Object.create(proto,propDescObj?)

    ② 读取对象原型

    调用方法: Object.getPrototypeOf(obj),返回obj的原型。

    ③ 检查一个对象是否是另一个对象的原型

    调用方法: Object.prototype.isPrototypeOf(obj),检查方法的接收者是否是obj的(直接或间接)原型。换句话说,接收者和obj是否在同一原型链上,且obj是否在接受者之前。

    ④ 特殊属性__proto__

    某些JavaScript引擎有特殊属性可以获取和设置对象的原型:__proto__。这样就可以直接访问[[prototype]]。

    var obj = {};
    console.log( obj.__proto__ === Object.prototype );  // true

    关于__proto__,你需要知道以下几点:

    1. __proto__读作“dunder proto”,“double underscore proto”的缩写。

    2. __proto__不属于ECMAScrip5标准。因此,你如果希望代码遵循这个标准,那么就不能使用__proto__。

    3. 然而,越来越多的引擎开始支持__proto__,而它也将成为ECMAScrip6的一部分。

    4. 下面的表达式检测引擎是否支持__proto__:

    Object.getPrototypeOf({__proto__ : null }) === null;

    (5) 设置和删除仅影响自有属性

    ① 设置属性

    原型属性会由多个对象共享。这种方式不会让我们破坏、“改变”原有属性,而只是影响当前对象。

    ② 删除继承的属性

    你只能删除自有属性,而不能删除继承属性。

    ③ 在原型链的任何位置改变属性

    如果你希望改变继承的属性,首先就是找到拥有这个属性的对象,然后改变这个对象的相应属性。

    (6) 遍历和检测属性

    遍历和检测属性的相关操作受如下情况影响。

    1. 继承(自由属性和继承属性)

    一个对象的自有属性直接存储在该对象中。继承的属性存储在该对象的其中一个原型中。

    2. 枚举(枚举属性和非枚举属性)

    属性的枚举是一个特性,标识为true或false。①  列出自有的属性键

    你可以列出所有自有的属性键,也可以只列出可枚举的属性键

    Object.getOwnPropertyNames(obj):返回obj的所有自有的属性键。

    Object.keys(obj):返回所有可枚举的属性键。

    注:属性通常都是可枚举的,因此你可以使用Object.keys(),特别是对已创建的对象。

    ② 列出所有的属性键

    如果你想列出所有的属性键(包括自有的和继承的),有两个选择。

    第一种就是使用for-in循环。

    第二种就是自己实现一个函数,遍历所有属性键(不仅是可枚举的)。

    后面写的东西可以参考《JavaScript权威指南》,暂时没有看到哪里有使用到,所以暂时就不看了。

  • 相关阅读:
    中国的人生路上是紧跟领导就会有回报
    重游三峡广场有感
    假如你没有我
    关于中小型软件企业技术管理的建议(转)
    街客
    游歌乐山有感
    高成就者的反常思维
    漫谈创业和管理-程序员5大思维障碍 (转)
    QQ情缘
    javascript library
  • 原文地址:https://www.cnblogs.com/luohaoran/p/5981988.html
Copyright © 2020-2023  润新知