• ECMAScript新特性【一】--Object.create


    Object.create(prototype, descriptors) :创建一个具有指定原型且可选择性地包含指定属性的对象

    参数:
    prototype 必需。  要用作原型的对象。 可以为 null。
    descriptors 可选。 包含一个或多个属性描述符的 JavaScript 对象。
    “数据属性”是可获取且可设置值的属性。 数据属性描述符包含 value 特性,以及 writable、enumerable 和 configurable 特性。

    如果未指定最后三个特性,则它们默认为 false。 只要检索或设置该值,“访问器属性”就会调用用户提供的函数。 访问器属性描述符包含 set 特性和/或 get 特性。

    复制代码

    var pt = {
            say : function(){
                console.log('saying!');    
            }
        }
        
        var o = Object.create(pt);
        
        console.log('say' in o); // true
        console.log(o.hasOwnProperty('say')); // false

    复制代码

    如果prototype传入的是null,创建一个没有原型链的空对象。

    var o1 = Object.create(null);
    console.dir(o1); // object[ No Properties ]

    当然,可以创建没有原型链的但带descriptors的对象;

    复制代码

    var o2 = Object.create(null, {
            size: {
                value: "large",
                enumerable: true
            },
            shape: {
                value: "round",
                enumerable: true
            }    
        });
        
        console.log(o2.size);    // large
        console.log(o2.shape);     // round
        console.log(Object.getPrototypeOf(o2));     // null

    复制代码

    也可以创建带属性带原型链的对象:

    复制代码

    var pt = {
            say : function(){
                console.log('saying!');   
            }
        }

    var o3 = Object.create(pt, { size: { value: "large", enumerable: true }, shape: { value: "round", enumerable: true } }); console.log(o3.size); // large console.log(o3.shape); // round console.log(Object.getPrototypeOf(o3)); // {say:...}

    复制代码

    最重要的是实现继承,看下面实例:

    复制代码

    //Shape - superclass
            function Shape() {
              this.x = 0;
              this.y = 0;
            }
            
            Shape.prototype.move = function(x, y) {
                this.x += x;
                this.y += y;
                console.info("Shape moved.");
            };
            
            // Rectangle - subclass
            function Rectangle() {
              Shape.call(this); //call super constructor.
            }
            
            Rectangle.prototype = Object.create(Shape.prototype);
            
            var rect = new Rectangle();
    
            console.log(rect instanceof Rectangle); //true.
            console.log(rect instanceof Shape); //true.
            
            rect.move(); //"Shape moved."

    复制代码

    不支持浏览器的兼容实现:

    1、简单实现,也是最常见的实现方式,没有实现第二个参数的功能:

    复制代码

    if (!Object.create) {
        Object.create = function (o) {
            if (arguments.length > 1) {
                throw new Error('Object.create implementation only accepts the first parameter.');
            }
            function F() {}
            F.prototype = o;
            return new F();
        };
    }

    复制代码

    2、复杂实现,实现第二个参数的大部分功能:

    复制代码

    if (!Object.create) {
    
        // Contributed by Brandon Benvie, October, 2012
        var createEmpty;
        var supportsProto = Object.prototype.__proto__ === null;
        if (supportsProto || typeof document == 'undefined') {
            createEmpty = function () {
                return { "__proto__": null };
            };
        } else {
            createEmpty = function () {
                var iframe = document.createElement('iframe');
                var parent = document.body || document.documentElement;
                iframe.style.display = 'none';
                parent.appendChild(iframe);
                iframe.src = 'javascript:';
                var empty = iframe.contentWindow.Object.prototype;
                parent.removeChild(iframe);
                iframe = null;
                delete empty.constructor;
                delete empty.hasOwnProperty;
                delete empty.propertyIsEnumerable;
                delete empty.isPrototypeOf;
                delete empty.toLocaleString;
                delete empty.toString;
                delete empty.valueOf;
                empty.__proto__ = null;
    
                function Empty() {}
                Empty.prototype = empty;
                // short-circuit future calls
                createEmpty = function () {
                    return new Empty();
                };
                return new Empty();
            };
        }
    
        Object.create = function create(prototype, properties) {
    
            var object;
            function Type() {}  // An empty constructor.
    
            if (prototype === null) {
                object = createEmpty();
            } else {
                if (typeof prototype !== "object" && typeof prototype !== "function") {
    
                    throw new TypeError("Object prototype may only be an Object or null"); // same msg as Chrome
                }
                Type.prototype = prototype;
                object = new Type();
    
                object.__proto__ = prototype;
            }
    
            if (properties !== void 0) {
                Object.defineProperties(object, properties);
            }
    
            return object;
        };
    }

    复制代码

    参考:

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/create

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/defineProperty

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/defineProperties

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

    https://github.com/kriskowal/es5-shim/blob/master/es5-sham.js

  • 相关阅读:
    单例模式
    C++继承-重载-多态-虚函数
    c++仿函数 functor
    常用排序算法实现与效率比较
    树的中序非递归遍历
    二叉树递归遍历
    队列的顺序存储框架
    栈的链式存储框架
    栈的顺序存储构架
    函数指针和回调函数
  • 原文地址:https://www.cnblogs.com/suizhikuo/p/3442223.html
Copyright © 2020-2023  润新知