Object构造函数(三)

4、对象原型的操作

(1)Object.setPrototypeOf() ES6  IE11

设置对象的原型(即内部 [[Prototype]] 属性)

Object.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或  null

当调用该方法 的时候,如果对象的[[Prototype]]是不可扩展(通过 Object.isExtensible()查看),就会抛出 TypeError异常。如果prototype参数不是一个对象或者null(例如,数字,字符串,boolean,或者 undefined),则什么都不做。否则,该方法将obj[[Prototype]]修改为新的值。

Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于 Object.prototype.__proto__ ,它被认为是修改对象原型更合适的方法。

注意传参,源对象  原型对象。返回修改了原型后的源对象。

        var obj1 = {
            name: "obj1"
        }
        var obj = {
            age: 24
        }
        var dict = Object.setPrototypeOf(obj, obj1);
        console.log(dict.name); obj1

警告: 由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.__proto__ = ... 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果你关心性能,你应该避免设置一个对象的 [[Prototype]]。相反,你应该使用 Object.create()来创建带有你想要的[[Prototype]]的新对象。 

(2)Object.getPrototypeOf() ES5  IE9

Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。如果没有继承属性,则返回 null 。

var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true

var reg = /a/;
Object.getPrototypeOf(reg) === RegExp.prototype; // true

(3)Object.create()方法创建一个新对象并指定对象原型  兼容性:ES5  IE9

        var obj = {
            name: "zhu",
            age: 24
        }
        var dict = Object.create(obj);
        console.log(dict);

        

 

5、Object上的两个工具方法

(1)Object.assign()浅复制对象  兼容性:Edge12  ES6

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。

Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。

如果属性不可写,会引发TypeError,如果在引发错误之前添加了任何属性,则可以更改target对象。

Symbol 类型的属性都会被拷贝,字符串也会作为一个对象进行拷贝。

        var sym = Symbol('foo'); //Symbol(foo)
        var str = "abc";
        var obj = {
            name: "zhu",
            age: 24,
            s: sym
        }
        var dict = Object.assign({},str,obj);
        console.log(dict);  {0: "a", 1: "b", 2: "c", name: "zhu", age: 24, s: Symbol(foo)}
        console.log(sym);  Symbol(foo)

Object.assign()拷贝的是(可枚举)属性值。假如源值是一个对象的引用,它仅仅会复制其引用值。

异常会打断后续的copy,但前面的copy是成功的,比如一个对象,一部分属性已经copy了,发生异常后,后续停止copy,而前面的属性copy成功。

原始类型会被包装,null 和 undefined 会被忽略。注意,只有字符串的包装对象才可能有自身可枚举属性。

(2)Object.is()判断两个值是否相等  Edge12  ES6

 判断两个值是否相同。如果下列任何一项成立,则两个值相同:

  • 两个值都是 undefined
  • 两个值都是 null
  • 两个值都是 true 或者都是 false
  • 两个值是由相同个数的字符按照相同的顺序组成的字符串
  • 两个值指向同一个对象
  • 两个值都是数字并且
    • 都是正零 +0
    • 都是负零 -0
    • 都是 NaN
    • 都是除零和 NaN 外的其它同一个数字

这种相等性判断逻辑和传统的 == 运算不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 "" == false 等于 true的现象),但 Object.is 不会做这种类型转换。

这与 === 运算符的判定方式也不一样。=== 运算符(和== 运算符)将数字值 -0 和 +0 视为相等,并认为 Number.NaN 不等于 NaN

兼容性:Edge12

兼容性写法:

if (!Object.is) {
  Object.is = function(x, y) {
    // SameValue algorithm
    if (x === y) { // Steps 1-5, 7-10
      // Steps 6.b-6.e: +0 != -0
      return x !== 0 || 1 / x === 1 / y;
    } else {
      // Step 6.a: NaN == NaN
      return x !== x && y !== y;
    }
  };
}

猜你喜欢

转载自blog.csdn.net/zyz00000000/article/details/106871849