先罗列下:html
prototype 原型express
class 类 函数
extensible attribute 可扩展属性this
prototype 属性:spa
prototype 大概回顾下,从建立方式着手, 字面量建立的对象其原型为 Object.prototype,create() 建立的其原型指向第一个参数给定对象; 若是经过构造函数建立的其 指向 构造函数 prototype 属性指向的对象。prototype
protptype 原型主要是用来继承属性以及方法。 那咱们怎么来查找和设置原型对象尼?code
ECMAScript3中经过 o.constructor.prototype 来获取对象原型, 在后来ECMAScript5中新增了 Object.getPrototypeOf() 其基本语法以下:htm
/** * Returns the prototype of an object. * @param o The object that references the prototype. */ getPrototypeOf(o: any): any;
经过不一样方式建立,并获取其原型对象对象
//自面量
var custom = { name:"wangjing" }; console.log(Object.getPrototypeOf(custom)); //构造函数
function Person(){ this.name = "文艺"; } Person.prototype.getName = function(){return name;} var person1 = new Person(); console.log(Object.getPrototypeOf(person1)); //create
var student = Object.create(person1); console.log(Object.getPrototypeOf(student)); {} Person { getName: [Function] } Person { name: '文艺' }
要想检测一个对象是不是另外一个对象的原型 , 请使用 Object.prototype.isPrototypeOf() 先来看看基础语法blog
/** * Determines whether an object exists in another object's prototype chain. * @param v Another object whose prototype chain is to be checked. */ isPrototypeOf(v: Object): boolean;
判断对象是否存在另外一个对象的原型链上 ,存在返回 true 不然 返回 false
//构造函数
function Person(){ this.name = "文艺"; } Person.prototype.getName = function(){return name;} var person1 = new Person(); Person.prototype.isPrototypeOf(person1) // true
class 属性:
中文译为 “类”,在这里表示就是对象的类,是一个字符串,在ECMAScript3以及 ECMAScript5中都没有直接获取或设置的属性,只能间接的经过 Object.prototype.toString()方式获取。默认的toString()方法返回以下的格式
[object class]
为何上面提到了默认的toString(),在大部分的状况下都覆盖了 Object.prototype.toString 方法,因此也只能经过 cell 方式进行调用;
//构造函数
function Person(){ this.name = "文艺"; } Person.prototype.getName = function(){return name;} var person1 = new Person(); function classOf(o){ if(o === undefined || o === null) return; return Object.prototype.toString.call(o).slice(8,-1); } console.log(classOf([]));// Array
console.log(classOf(new Date())); // Date
console.log(classOf(/\w/)); // RegExp
console.log(classOf(Person)); // Function
console.log(classOf(person1)); //Object
console.log(classOf(Window)); //Window
从上面能够看出,经过内置对象构造函数(Array,Date)的生成的对象类属性返回值与构造函数名称相对应; 宿主对象也是同样, 经过自面量,create()建立的对象,其类名为 object, 自定义的对象,也返回 object; 因此经过class属性是没有办法区分对象的类
可扩展性:
可扩展属性决定是否能够往对象添加新的属性。 全部的内置对象和自定义对象都是显示能够扩展的。 宿主对象默认是能够扩展的,其可扩展也是由JavaScirpt引擎和ECMAScript5所规定的。
若是想设置或查看对象可扩展性,ECMAScript5中提供两个方法 Object.isExtensible()、 Object.preventExtensions()。
Object.isExtensible() 返回一个值,指示是否新的属性能够添加到一个对象
/** * Returns a value that indicates whether new properties can be added to an object. * @param o Object to test. */ isExtensible(o: any): boolean;
Object.preventExtensions() 阻止添加属性到对象中
/** * Prevents the addition of new properties to an object. * @param o Object to make non-extensible. */ preventExtensions<T>(o: T): T;
实例1:
function Person(){ this.name = "文艺"; } Person.prototype.getName = function(){return name;} var person1 = new Person(); console.log("before "+Object.isExtensible(person1)) //true
Object.preventExtensions(person1); console.log("after " + Object.isExtensible(person1)) // false
虽然不能够添加 可是仍是能够修改其自有属性的特性 configurable、enumerable、writable 可是其修改原则仍是遵循 对象属性 讲述内容
function Person(){ this.name = "文艺"; } Person.prototype.getName = function(){return name;} var person1 = new Person(); Object.preventExtensions(person1); Object.defineProperty(person1,"name",{ configurable:false });
console.log(Object.getOwnPropertyDescriptor(person1,"name"));
当configurable其属性为 ture时,属性能够被删除,
function Person(){ this.name = "文艺"; } Person.prototype.getName = function(){return name;} var person1 = new Person(); Object.preventExtensions(person1); delete person1.name // true
console.log(person1.name); // undefined
其只对影响对象自己的可扩展性;对其原型以及原型链上的对象不会有影响; 假如对象原型上添加某些属性时,在不可扩展对象也是能够访问到的
function Person(){ this.name = "文艺"; } var person1 = new Person(); Object.preventExtensions(person1); console.log(person1.getName); // undefined
Person.prototype.getName = function(){return this.name;} console.log(person1.getName()); // "文艺"
与 preventExtensions 类似的一个方法 Object.seal() 先来了解了解
Object.seal()
基本语法
/** * Prevents the modification of attributes of existing properties, and prevents the addition of new properties. * @param o Object on which to lock the attributes. */ seal<T>(o: T): T;
这个方法 阻止对象扩展,而且把自有属性可配置属性设置为 false ,也就是说其属性不能被删除或配置, 可是其读写属性是能够修改的。
既然有锁定方法,那么确定与之对应的检测方法 Object.isSealed()
/** * Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object. * @param o Object to test. */ isSealed(o: any): boolean;
实例一
function Person(){ this.name = "文艺"; } var person1 = new Person(); console.log(Object.getOwnPropertyDescriptor(person1,"name")); // { value: '文艺',writable: true,enumerable: true,configurable: true }
Object.seal(person1); Person.prototype.getName = function(){return this.name;} // 正常添加
console.log(Object.getOwnPropertyDescriptor(person1,"name")); // { value: '文艺',writable: true,enumerable: true,configurable: false }
delete person1.name //TypeError: Cannot delete property 'name' of #<Person>
console.log(person1.getName()); // "文艺"
与 preventExtensions 同样,只对影响对象扩展性,并不会影响其原型链上的对象。
Object.freeze() 将更严格的锁定对象 ------- 冻结
freeze() 不只锁定对象不能进行扩展,而且把自有属性设置不可配置以及设置为只读属性(若是是取值器属性而且其包含 seter 方法,那么仍是能够正常对属性进行写操做);
语法:
/** * Prevents the modification of existing property attributes and values, and prevents the addition of new properties. * @param o Object on which to lock the attributes. */ freeze<T>(o: T): T;
isFrozen() 用来检测对象是否被冻结了
/** * Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object. * @param o Object to test. */ isFrozen(o: any): boolean;
实例:
function Person(){
this.name = "文艺"; } var person1 = new Person(); console.log(Object.getOwnPropertyDescriptor(person1,"name")); // { value: '文艺',writable: true,enumerable: true,configurable: true } Object.freeze(person1); console.log(Object.isFrozen(person1)); // true
Person.prototype.getName = function(){return this.name;} // 正常添加 console.log(Object.getOwnPropertyDescriptor(person1,"name")); // { value: '文艺',writable: false,enumerable: true,configurable: false }
//delete person1.name //TypeError: Cannot delete property 'name' of #<Person> //person1.name = "wj"; //TypeError: Cannot assign to read only property 'name' of object '#<Person>'
console.log(person1.getName()); // "文艺"
与 preventExtensions 、seal 同样,只对影响对象扩展性,并不会影响其原型链上的对象。
能够利用 preventExtensions 、seal、freeze 三个方法来搭配使用,构建一个彻底封闭的对象。
var ooo = Object.seal( Object.create( Object.freeze({x:1}), { y:{value:2,writable:true} } ) ); console.log(ooo); // {}
console.log(ooo.x); // 1
console.log(ooo.y); // 2 这里是不可枚举因此打印时 看到到