• 对象相关的——————三个属性


    先罗列下:

      prototype 原型

      class 类 

      extensible attribute  可扩展属性

    prototype 属性:

      prototype 大概回顾下,从创建方式着手, 字面量创建的对象其原型为 Object.prototype,create() 创建的其原型指向第一个参数给定对象;  如果通过构造函数创建的其 指向 构造函数 prototype 属性指向的对象。

    protptype 原型主要是用来继承属性以及方法。 那我们怎么来查找和设置原型对象尼?

      

      ECMAScript3中通过 o.constructor.prototype 来获取对象原型, 在后来ECMAScript5中新增了 Object.getPrototypeOf() 其基本语法如下:

      

       /**
          * 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() 先来看看基础语法

     /**
          * 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  这里是不可枚举所以打印时 看到到

      

  • 相关阅读:
    排序应用于链表
    线性时间排序算法
    排序算法
    2017计蒜客蓝桥杯模拟赛5
    第六届河南省赛 River Crossing 简单DP
    POJ 3061 Subsequence 尺取法 POJ 3320 Jessica's Reading Problem map+set+尺取法
    天梯赛 L2-020. 功夫传人 BFS
    天梯赛 L2-019. 悄悄关注 map
    配置在Chrome,Firefox中打开
    http响应状态码大全
  • 原文地址:https://www.cnblogs.com/czhyuwj/p/5889804.html
Copyright © 2020-2023  润新知