前端开发者进阶之ECMAScript新特性

时间:2022-11-09 18:50:34

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

 

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

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

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

前端开发者进阶之ECMAScript新特性
var pt = {
say :
function(){
console.log(
'saying!');
}
}

var o = Object.create(pt);

console.log(
'say' in o); // true
console.log(o.hasOwnProperty('say')); // false
前端开发者进阶之ECMAScript新特性

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

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

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

前端开发者进阶之ECMAScript新特性
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
前端开发者进阶之ECMAScript新特性

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

前端开发者进阶之ECMAScript新特性
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:...}
前端开发者进阶之ECMAScript新特性

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

前端开发者进阶之ECMAScript新特性
//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."
前端开发者进阶之ECMAScript新特性

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

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

前端开发者进阶之ECMAScript新特性
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();
};
}
前端开发者进阶之ECMAScript新特性

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

前端开发者进阶之ECMAScript新特性
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 特性。

前端开发者进阶之ECMAScript新特性
var pt = {
say :
function(){
console.log(
'saying!');
}
}

var o = Object.create(pt);

console.log(
'say' in o); // true
console.log(o.hasOwnProperty('say')); // false
前端开发者进阶之ECMAScript新特性

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

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

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

前端开发者进阶之ECMAScript新特性
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
前端开发者进阶之ECMAScript新特性

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

前端开发者进阶之ECMAScript新特性
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:...}
前端开发者进阶之ECMAScript新特性

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

前端开发者进阶之ECMAScript新特性
//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."
前端开发者进阶之ECMAScript新特性

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

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

前端开发者进阶之ECMAScript新特性
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();
};
}
前端开发者进阶之ECMAScript新特性

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

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