zoukankan      html  css  js  c++  java
  • Object-API—02

    (09)Object.setPrototypeOf() & Object.getPrototypeOf() & __proto__

    JS的对象继承是通过原型链实现的。ES6提供了更多原型对象的操作方法

    ①__proto__属性

    这个属性用来读取或者设置当前对象的原型对象(prototype

     1 //  ES5的写法
     2 const fatherObj = {}
     3 const sonObj = {
     4     method:function(){}
     5 }
     6 obj.__proto__ = fatherObj
     7 
     8 // ES6的写法
     9 var sonObj01 = Object.create(fatherObj)
    10 sonObj01.method = function(){}
    • __proto__属性没有写入ES6的正文,而是写入了附录,原因是这个属性前后带有下划线,说明它本质上是一个内部属性,而不是一个正式的对外的API,只是由于浏览器的广泛支持,才被加入了ES6。
    • 标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。因此,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性。而是使用下面的Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替。
    • 如果一个对象本身部署了__proto__属性,该属性的值就是对象的原型

    ② Object.setPrototypeOf()

    这个方法的作用与__proto__的作用相同,用来设置一个对象的原型对象(prototype),返回参数对象本身。它是ES6正式推荐的设置原型对象的方法。

    1 // 格式
    2 Object.setPrototypeOf(object,prototype)
    3 
    4 // 用法
    5 const o = Ojbect.setPrototypeOf({},null)

    这个方法等同于下面的函数:

    1 function setPrototypeOf(obj,proto){
    2     obj.__proto__ = proto;
    3     return obj
    4 }

    示例:

     1 let proto = {}
     2 let obj = { a:1 }
     3 Object.setPrototypeOf(obj,proto)
     4 
     5 proto.b = 2
     6 proto.c = 3
     7 
     8 obj.a  // 1
     9 obj.b  // 2
    10 obj.c  // 3

    上面代码将proto对象设为obj对象的原型,所以从obj对象可以读取proto对象的属性

    注意:

    • 如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果
    • 由于undefinednull无法转为对象,所以如果第一个参数是undefinednull,就会报错(null和undefined的区别可见阮一峰博客

    ③Object.getPrototypeOf()

    这个方法与Object.setPrototypeOf()方法配套,用于读取一个对象的原型对象

    Object.getPrototypeOf(obj)

    注意:

    • 如果参数不是对象,会被自动转为对象
    • 如果参数是undefinednull,它们无法转为对象,所以会报错

    (10)Object.is()

    ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。

     ES6提出了"Same-Value equuality"(同值相等)算法,用来解决这个问题。Object.is()就是部署这个算法的新方法。它用来比较两个值是否严格相等,与(===)的行为基本一致

    1 Object.is('foo', 'foo')
    2 // true
    3 Object.is({}, {})
    4 // false

    ES5可以通过以下代码,部署Object.is

     1 Object.defineProperty(Object, 'is', {
     2   value: function(x, y) {
     3     if (x === y) {
     4       // 针对+0 不等于 -0的情况
     5       return x !== 0 || 1 / x === 1 / y;
     6     }
     7     // 针对NaN的情况
     8     return x !== x && y !== y;
     9   },
    10   configurable: true,
    11   enumerable: false,
    12   writable: true
    13 });

    (11)Object.isExtensible()  & Object.isFrozen() & Object.isSealed()

    ①Object.isExtensible() 方法判断一个对象是否是可扩展的.

    默认情况下,对象是可扩展的:即可以为他们添加新的属性。以及它们的 __proto__ 属性可以被更改。Object.preventExtensionsObject.seal 或 Object.freeze 方法都可以标记一个对象为不可扩展(non-extensible)

     1 // 新对象默认是可扩展的.
     2 var empty = {};
     3 Object.isExtensible(empty); // === true
     4 
     5 // ...可以变的不可扩展.
     6 Object.preventExtensions(empty);
     7 Object.isExtensible(empty); // === false
     8 
     9 // 密封对象是不可扩展的.
    10 var sealed = Object.seal({});
    11 Object.isExtensible(sealed); // === false
    12 
    13 // 冻结对象也是不可扩展.
    14 var frozen = Object.freeze({});
    15 Object.isExtensible(frozen); // === false

    注意:

    • 在 ES5 中,如果参数不是一个对象类型,将抛出一个 TypeError 异常。在 ES6 中, non-object 参数将被视为一个不可扩展的普通对象,因此会返回 false 。

    Object.isFrozen() 与 Object.isSealed() 分别用来对应Object.freeze()和Object.seal()

    (12)Object.hasOwnProperty()

    hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。

    1         let obj = {
    2             name: "张三",
    3             age: 26
    4         }
    5         console.log(obj.hasOwnProperty('name'));  // true
    6         console.log(obj.hasOwnProperty('gender'));  // false

    (13)Object.isPrototypeOf()

    isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上

    注意:isPrototypeOf() 与 instanceof 运算符不同。在表达式 "object instanceof AFunction"中,object 的原型链是针对 AFunction.prototype 进行检查的,而不是针对 AFunction 本身。

     1         function Foo() { }
     2         function Bar() { }
     3         function Baz() { }
     4 
     5         Bar.prototype = Object.create(Foo.prototype) // 让Bar继承自Foo
     6         Baz.prototype = Object.create(Bar.prototype) // 让Baz继承自Bzr  
     7         // 继承关系:Foo->Bar->Baz
     8         //         父--------->子
     9 
    10         var baz = new Baz()
    11         console.log(Baz.prototype.isPrototypeOf(Baz));
    12         console.log(Bar.prototype.isPrototypeOf(baz)); // true
    13         console.log(Foo.prototype.isPrototypeOf(baz)); // true
    14         console.log(Object.prototype.isPrototypeOf(baz)); // true

    注意与instanceof操作符的不同:

    • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
    • isPrototypeOf() 作用在两个对象的比较

     (14)Object.propertyIsEnumerable()

    propertyIsEnumerable() 方法返回一个布尔值,表示指定的属性是否可枚举

     1 const object1 = {};
     2 const array1 = [];
     3 object1.property1 = 42;
     4 array1[0] = 42;
     5 
     6 console.log(object1.propertyIsEnumerable('property1'));
     7 // expected output: true
     8 
     9 console.log(array1.propertyIsEnumerable(0));
    10 // expected output: true
    11 
    12 console.log(array1.propertyIsEnumerable('length'));
    13 // expected output: false

    (15)Object.toLocaleString() & Object.toString()

    ①toLocaleString() 方法返回一个该对象的字符串表示。此方法被用于派生对象为了特定语言环境的目的(locale-specific purposes)而重载使用

    用于覆盖toLocaleString的对象。在Object下的对象被改写了:

    toString() 方法返回一个表示该对象的字符串

     每个对象都有一个toString()方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString()方法被每个Object对象继承。如果此方法在自定义对象中未被覆盖,toString()返回“[object type]”,其中type是对象的类型。以下代码说明了:

    var o = new Object();
    o.toString(); // returns [object Object]

    可以使用toString()检测对象类型

    可以通过toString(),来获取每个对象的类型。为了每个对象都能铜鼓Object.prototype.toString()来检测,所以需要使用call()或者apply的形式来调用。

    1 var toString = Object.prototype.toString;
    2 
    3 toString.call(new Date); // [object Date]
    4 toString.call(new String); // [object String]
    5 toString.call(Math); // [object Math]
    6 
    7 //Since JavaScript 1.8.5
    8 toString.call(undefined); // [object Undefined]
    9 toString.call(null); // [object Null]

     (16)Object.valueOf()

    valueOf() 方法返回指定对象的原始值。

     JavaScript调用valueOf方法将对象转换为原始值。你很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。

    确实么用过,想了解可以查看MDN

  • 相关阅读:
    C#中处理鼠标和键盘的事件
    C#中处理鼠标和键盘的事件
    C#中处理鼠标和键盘的事件
    mpich2安装
    算法题推箱子
    LINUX终端下windows盘的位置
    Linux头文件和库文件添加环境变量与GCC编译器添加INCLUDE与LIB环境变量
    第九章顺序容器重学C++之《 C++ PRIMER》
    sed中使用变量
    抛出异常
  • 原文地址:https://www.cnblogs.com/codexlx/p/14314813.html
Copyright © 2011-2022 走看看