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