前端开发者进阶之ECMAScript新特性--Object.create

前端开发者进阶之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;
    };
}

前端开发者进阶之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;
    };
}
时间: 2024-10-19 20:48:41

前端开发者进阶之ECMAScript新特性--Object.create的相关文章

前端入门21-JavaScript的ES6新特性

声明 本篇内容全部摘自阮一峰的:ECMAScript 6 入门 阮一峰的这本书,我个人觉得写得挺好的,不管是描述方面,还是例子,都讲得挺通俗易懂,每个新特性基本都还会跟 ES5 旧标准做比较,说明为什么会有这个新特性,这更于理解. 所以,后续不会再写个关于 ES6 系列的文章了,就在这篇里大概的列举一下,大体清楚都有哪些新特性就好了,以后需要用时再去翻一翻阮一峰的书. 正文-ES6新特性 ES6 新标准规范相比于 ES5 旧标准规范中,无非就三个方面的改动:新增.更新.废弃. 由于更新和废弃需要

前端神器 Firebug 2.0 新特性一览

如果你从事Web前端方面的开发工作,那么对Firebug一定不会陌生,这是Firefox浏览器的一款插件,集HTML查看和编辑.Javascript控制台.网络状况监视器于一体,给Web开发者带来了极大的便利,堪称Web前端开发神器. 最新版本Firebug 2.0即将发布,下面就来看看这个大版本中有哪些改进. 1.  基于新的Firefox调试引擎(JSD2) 2.  新的UI,以匹配Firefox 29版本中引入的Australis主题 3.  Script面板支持语法高亮 4.  允许检查

前端(七):ES6一些新特性

一.变量 1.var关键字的弊端 var关键字的弊端:1.可以重复声明变量:2.无法限制变量修改:3.没有会计作用域,只有函数作用域. <html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><input type="button" value="

Java进阶(11) - Java8+新特性

接口中的默认方法,接口终于可以有方法实现了,使用注解即可标识出默认方法. lambda表达式实现了函数式编程,通过注解可以声明一个函数式接口,该接口中只能有一个方法,这个方法正是使用lambda表达式时会调用到的接口. Option类实现了非空检验 新的日期API 各种api的更新,包括chm,hashmap的实现等 Stream流概念,实现了集合类的流式访问,可以基于此使用map和reduce并行计算. 参照:https://h2pl.github.io/2018/07/10/Java核心技术

一小时学会ECMAScript6新特性(二)

1.对象属性名 es5中我们为一个对象添加属性可以用如下代码: let foods = {}; foods.dessert = '蛋糕'; console.log(foods) 但是属性名中间有空格则不能用点的形式添加,es6中的属性名可以有空格: let foods = {}; foods.dessert = '蛋糕'; foods['hot drink'] = '可乐' console.log(foods) 方括号中还可以用变量的形式引入: let foods = {}, drink = '

前端开发者不得不知的ES6十大特性

前端开发者不得不知的ES6十大特性 转载 作者:AlloyTeam 链接:http://www.alloyteam.com/2016/03/es6-front-end-developers-will-have-to-know-the-top-ten-properties/ ES6(ECMAScript2015)的出现,无疑给前端开发人员带来了新的惊喜,它包含了一些很棒的新特性,可以更加方便的实现很多复杂的操作,提高开发人员的效率. 本文主要针对ES6做一个简要介绍. 主要译自:  http://

34.JS 开发者必须知道的十个 ES6 新特性

JS 开发者必须知道的十个 ES6 新特性 这是为忙碌的开发者准备的ES6中最棒的十个特性(无特定顺序): 默认参数 模版表达式 多行字符串 拆包表达式 改进的对象表达式 箭头函数 =&> Promise 块级作用域的let和const 类 模块化 注意:这个列表十分主观并且带有偏见,其他未上榜的特性并不是因为没有作用,我这么做只是单纯的希望将这份列表中的项目保持在十个. 首先,一个简单的JavaScript时间线,不了解历史的人也无法创造历史. 1995年:JavaScript以LiveS

firefox-Developer开发者站点——关于Object.create()新方法的介绍

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象. 语法 Object.create(proto, [ propertiesObject ]) 参数 proto 一个对象,作为新创建对象的原型. propertiesObject 可选.该参数对象是一组属性与值,该对象的属性名称将

android 7.0 新特性 和对开发者的影响

android 7.0新特性 - jiabailong的专栏 - 博客频道 - CSDN.NEThttp://blog.csdn.net/jiabailong/article/details/52411300 android 7.0对开发者会有哪些影响 - jiabailong的专栏 - 博客频道 - CSDN.NEThttp://blog.csdn.net/jiabailong/article/details/52411353 android 7.0 多窗口及新特性demo - jiabail