在javaScript
当中,如果是只有内部才能访问的属性,那么使用[[ ]]
括号括起来的。
属性类型
数据属性
[[Configurable]]
: 默认为true
。能否delete
、能否修改除Writeable
之外的数据属性、能否把属性修改为访问器属性。一旦改为false
,就不能修改回true
。[[Enumerable]]
: 默认为true
。能否通过for-in
返回属性。[[Writable]]
: 默认为true
。是否可写。[[Value]]
:默认为undefined
。数据值。
配置使用Object.defineProperty
,使用它配置一个新的属性时, 数据属性未指定部分默认值为false
。
var a = {}
Object.defineProperty(a, 'name', {
Configurable:true,
Writable:true,
Enumerable: true
})
访问器属性
[[Get]]
: 读取属性时调用的函数,表示可读。[[Set]]
: 设置属性时调用的函数,表示可写。
访问器属性不能直接定义,也要使用Object.defineProperty
配置。
var a = {
_year: 10
}
Object.defineProperty(a, 'year', {
get: function() {
return this._year // 如果直接使用this.year, 那么会不断触发get,所以才定义了一个_year
},
set: function(value) {
this._year = value
}
})
定义多个属性
使用Object.definedProperties()
var a = { }
Object.defineProperties(a, {
_year: {
writeable: true,
value: 2004
},
year: {
get: function() {
return this._year
},
set: function(value) {
this._year = value
}
}
})
读取数据属性
使用Object.getOwnPropertyDescriptor(obj, 字段)
, 不会沿着obj
的 原型链去找属性
创建对象
工厂模式
解决代码重复问题,但是由于都是使用Object
,所以无法区分每个对象的类型, 例如Array
就是一种类型
function createObj(name, age) {
var o = new Object()
o.name = name
o.age = age
return o
}
构造函数模式
优点是可以为对象创建一个特定的类型,缺点是无法实现共享,每次创建都需要将所有可复用的属性创建一遍。虽然方法可以放到全局中,但是这不是明智之举。
function Test(name, age) {
this.name = name
this.age = age
}
var test1 = new Test('cas', 12)
var test2 = new Test('cvdv', 13)
原型模式
可以实现共享、缺点是多个实例都可以修改原型,不安全。
function Test() {
}
Person.prototype = {
constructor: Test, // 这里如果不指定,默认是指向Object, 而且手动指定之后[[Enumerable]]变为true
name: 'cascas',
sayName: function () {
return this.name
}
}
var test1 = new Test()
instanceOf
: 用来判定某个实例是否是某个对象的实例,原型链上出现过的构造函数都会返回true
,isPrototypeof
也 一样- 判断原型链关系:
Test.prototype.isPrototypeof(test1)
- 获取对象的
prototype
:Object.getPrototypeof(test1)
- 判断是否为实例的属性:
test1.haseOwnProperty('name')
in
操作符会遍历原型链,和for-in
不一样的是,当Enumerable
为false
的 时候,它能够访问,因为Enumerable
是是否可枚举- 获得实例上所有可以枚举的属性:
Object.keys(test1)
- 获得实例上所有属性:
Object.getOwnPropertyNames()
组合使用构造函数和原型模式
这是使用得最多的一种模式
funtion Person(name, age) {
this.name = name
this.age = age
}
Person.prototype = {
constructor: Person,
sayName: function () {
console.log(this.name)
}
}
var person1 = new Person()
寄生构造函模式
和工厂模式类似
function Person(name, age) {
var o = new Object()
o.name = name
o.age = age
return o
}
比如我们想创建一个具有额外方法的Array
但是不能修改原有构造函数,这个时候就可以使用这个。
稳妥构造函数模式
function Person(name, age) {
var o = new Object()
// 传递进来的name和age不要传给o对象
return o
}
特点是比较安全,给返回的o
对象添加其他的方法不能访问内部的name、age
,因为o
的this
不能访问到它们。