zoukankan      html  css  js  c++  java
  • 03.JavaScript 面向对象精要--理解对象

    JavaScript 面向对象精要--理解对象

    尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的
    对象。JavaScript中的对象是动态的。

    一.定义属性
    当一个属性第1次被添加给对象时JavaScript在对上上调用了一个名为
    [[Put]]的内部方法,该方法会在对象上创建一个新节点保存属性,就像
    哈希表上第一次添加一个键一样这个操作不仅指定了初始值
    也定义了属性的一些特征

    1.1 [[Put]]内部方法
    [[Put]]在对象上创建一个自有属性
    1.2 [[Set]]内部方法
    当一个属性被赋予一个新值时,调用对象上的[[Set]]内部方法

    var person1 = {
        name : 'Nicholas'//调用person1上的[[Put]]
    }
    var person2 = new Object();
    person2.name = 'Nicholas'; //调用person2上的[[Put]]
    person1.name = 'Greg'; //调用person1上的[[Set]]
    perosn2.name = 'Greg' //调用person2上的[[Set]]


    二.属性探测
    由于属性可以在任何时候添加,所以有时候就有必要
    检查对象上是否己有属性
    if判断中的值是一个 对象、非空字符串、非0数字和false时
    判断为 真;当值为:null、underfined、0、false、NaN或
    空字符串时为 假。


    2.1 in 探测
    in操作符会检查自有属性和原型属性。

    var person = {
      name : 'Nicholas'
    }
    console.log('name' in person) //true;
    console.log('age' in person) //false;
    console.log('toString' in person) //true;
    2.2 hasOwnProperty() 探测
    obj.hasOwnProperty('name')只会探测自有属性。
    console.log(person.hasOwnProperty('name')) //true;
    console.log(person.hasOwnProperty('toString'));//false


    三.删除属性
    delete操作符删除对象上属性时候,在对象上调用[[Delete]]
    内部方法,你可以认为该操作在哈希表中移除一个键值对。
    delete操作成功返回true。

    var person = {
        name : 'Nicholas'
    }
    console.log('name' in person); //true;
    delete person.name //调用[[Delete]] 返回true
    console.log('name' in person); //false
    console.log(person.name); //undefined

    四.属性枚举
    4.1 for-in 枚举
    所有添加的属性默认都是可枚举的,可以要for-in循环便利
    它们,可枚举属性内部特征[[Enumerable]]都被设置为true
    for-in会枚举一个对象的所有的可枚举的属性并将属性名赋
    给一个变量

    var property;
    for(perperty in object){
    console.log('Name'+property);
    console.log('Value'+object[property]);
    }

    4.2 Object.keys() 方法
    Object.keys(obj)可以取得可枚举属性的名字的 数组
    只返回 自有 属性,不会遍历原型属性
    var properties = Object.keys(obj);
    var i,len
    for(i = 0,len = properties.length;i<len;i++){
    console.log('Name'+ properties[i]);//对象的键名
    console.log('Value' = obj[properties[i]]);//对象的值

    }
    4.3 propertyIsEnumerable() 方法
    并不是所有对象都是可枚举的,实际上,对上大部分原生方法的
    [[Enumerable]]特征 为 false,你可以使用 propertyIsEnumerable()
    方法检查一个属性是否可枚举。每个对象都拥有该方法。

    var person = {
        name : 'Nicholas'
    }
    console.log('name' in person) //true
    console.log(person.propertyIsEnumerable(name)) //true;
    var properties = Object.keys(person);
    console.log('length' in properties); //true;
    console.log(properties.propertyIsEnumerable('length')) //false;


    五.属性类型
    属性有两种类型:数据属性 和 访问器属性。
    访问器属性不包含值而是定义一个当属性被读取时调用的函数
    getter和一个当属性被写入时调用的函数 setter。
    5.1 getter和setter

    定义一个访问器属性name, _name保存了访问器属性的实际值。
    (_约定的命名规范)。

    var person = {
        _name : 'Nicholas',
        get name() {
            console.log('name');
            return this._name;//返回属性值
        },
        set name(val){
            console.log('set name val');
            this._name = val;//设置属性值
        }
    }
    console.log(person.name); //返回'Nicholas'
    person.name = 'Greg'; //如果只设置了getter 无法改变name的值
    console.log(person.name); //返回'Greg'


    你并不一定同时定义setter和getter,如果只定义了getter
    该属性就变成了 只读

    六.属性特征
    ECMAScript5引入了多种方法来和属性特征之间互动

    6.1 通用特征 [[Enumerable]] [[Configurable]]
    [[Enumerable]] 决定了是否可以遍历该属性;
    [[Configurable]] 决定了该属性是否可配置;
    Object.defineProperty() 方法 可以用来改变属性的特征。
    接受 3 个参数 :该属性的对象、该属性名、设置特征的对象。

    var person = {
        name : 'Nicholas'
    }
    Object.defineProperty(person,'name',{
        enumerable : false,
        configurable : false
    })
    console.log(
    'name' in person) //true; console.log(person.propertyIsEnumerable('name')) //false; var propers = Object.keys(person); console.log(propers.length) // 0 delete person.name; //无法删除 console.log(person.name) //'Nicholas' Object.defineProperty(person,'name',{ configurable : true //报错 })

    6.2 数据属性特征
    数据属性包含 访问器属性不具有的两个特征。
    [[Value]]和 [[Writable]]
    [[Value]] 保存属性的值;
    [[Writable]] 属性是否可以写入

    var person = {
        name : 'Nicholas'
    }
    Object.defineProperty(person,'name',{
        value : 'Greg',
        enumerable : true,
        configurable : true,
        writable : true
    })


    当Object.defineProperty()被调用时,首先检查属性是否存在。
    如果不存在,根据对象指定的特征创建值。
    当你使用Object.defineProperty()创建属性时,一定要记得为
    所有特征制定一个值,否则 布尔型 的特征会被默认设置为 false

    6.3 访问器属性
    访问器属性也有两个额外的特征,访问器属性不需要存储值
    因此就没有[[Value]]和[[Writable]]。取而代之的是[[Get]]
    和 [[Set]]和对象直面形式的 getter和setter一样。

    var person = {
        _name : 'Nicholas',
        get name(){
            return this._name;
        },
        set name(val){
            this._name = val;
        }
    }
    //这段代码可以改写成:
        var person = {
            _name : 'Nicholas'
        }    
    Object.defineProperty(person,'name',{
        get : function(){
            return this._name;
        },
        set : functiono(val){
            this._name = val;
        },
      enumerable : true,
      configurable : true
    })            

    6.4 定义多重属性
    使用Object.defineProperties(obj,{})来为一个对象
    定义多个属性的特征

    var person = {};
    Object.defineProperties(person,{
    _name : {
    value : 'Nicholas',
    enumerable : true,
    configurable : true,
    writable : true
    },
    name : {
    get : function(){
    return this.name;
    },
    set : function(val){
    this.name = val;
    },
    enumerable : true,
    configurable : true
    
    }
    })

    定义了_name数据属性和name访问器属性。

    6.5 获取属性的特征
    使用Object.getOwnPropertyDescriptor()方法返回属性的特征
    的一个对象即使没有被显示的定义。
    接受两个参数 属性所在的对象、属性名。

    var person = {
      name = 'Nicholas'
    }
    var descriptor = Object.getOwnPropertyDescriptor(person,'name');
    console.log(descriptor.enumerable); //true
    console.log(descriptor.configurable); //true
    console.log(descriptor.writable); //true
    console.log(descriptor.value); //'Nicholas'

    七.禁止修改对象
    [[Extensible]]是一个布尔值,它指明该对象特征是否可被修改。
    你创建的所有对象默认都是可被扩展的,意味着新的属性可以随时
    添加

    7.1 禁止扩展
    Object.preventExtensions()方法创建一个不可扩展的对象。
    Object.isExtensible()来检查[[Extensible]]的值。

    var person = {
        name : 'Nicholas'
    }
    console.log(Object.isExtensible(person)); //ture
    Object.preventExtensions(person);
    console.log(Object.isExtensible(person)); //flase
    person.sayName = function(){
    console.log(this.name);
    };
    console.log('sayName' in person); //false

    7.2 对象封印
    对象封印是创建一个不可扩展的对象的第二个方法。
    一个封印的对象是不可扩展且所有属性都不可配置
    如果一个对象被封印,只能读写他的属性
    使用Object.seal() 方法封印对象
    被调用时 [[Extensible]]和[[Configurable]]特征为 false.
    可以用Object.isSealed()判断对象是否被封印。

    var person = {
        name : 'Nicholas'
    }
    console.log(Object.isExtensible(person)) // 是否扩展 true
    console.log(Object.isSealed(person))    //是否被封印 false
    Object.seal(person) //封印对象
    console.log(Object.isExtensible(person)) // 是否扩展 false
    console.log(Object.isSealed(person))    //是否被封印 true

    7.3 对象冻结
    创建不可扩展的第三个方法就是冻结它。
    如果一个对象被冻结,则不能在其上添加和删除属性
    不能改变属性类型,也不能写入任何数据属性。
    Object.freeze()来冻结一个对象
    Object.isFrozen()判断一个对象是否被冻结。

    var person = {
        name : "Nicholas"
    }
    console.log(Object.isExtensiable(person)) //是否扩展 true
    console.log(Object.isSealed(person)) //是否封印 false
    console.log(Object.isFrozen(person)) //是否冻结 false
    Object.freeze(person) //冻结对象
    console.log(Object.isExtensiable(person)) //是否扩展 false
    console.log(Object.isSealed(person)) //是否封印 true
    console.log(Object.isFrozen(person)) //是否冻结 true
  • 相关阅读:
    2013年发生云盘圈地大战的原因(1是因为流量成本降价,2是因为硬盘降价,3是免费是未来的商业模式)
    硬盘可以支持140万小时(也就是159年)的MTBF(硬盘只是一次性的投入)
    百度不愧为流量之王(空间的问题只是满足了用户之间的“虚荣”,而功能的完善才最终决定了事件的走向)
    唐太宗用人 不以一恶忘其善(使用每个人的特点去做事情)
    js模块化编程
    Flux
    安装配置gerrit
    redis
    Ruby
    演进式设计
  • 原文地址:https://www.cnblogs.com/ShareBeautiful/p/5905726.html
Copyright © 2011-2022 走看看