對象相關的——————三個屬性

先羅列下: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"));
  // { value: '文藝',writable: true,enumerable: true,configurable: false }

 

當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 這裏是不可枚舉因此打印時 看到到
相關文章
相關標籤/搜索