JavaScript Advanced Programming (4th Edition) Reading Sharing Note Recording
Applicable to comrades who are just getting started
- The usual way to create custom objects is to create a new instance of Object and then add properties and methods to it.
let person = new Object()
person.name = 'Tom'
person.age = 18
person.sayName = function(){
//示 this.name 的值,这个属性会解析为 person.name。
console.log(this.name) // Tom
}
The above code creates an object named person with two properties (name, age) and one method (sayName).
- Create objects using object literals
let person = {
name:'Tom',
age:18,
sayName(){
console.log(this.name) //Tom
}
}
attribute type
data attribute
- [[Configurable]] : Indicates whether the property can be deleted and redefined by delete , whether its characteristics , and whether it can be changed to an accessor property. By default, this feature is true
- [[Enumerable]] : Indicates whether the attribute can be returned by a for-in loop. By default, this feature is true.
- [[Writable]] : Indicates whether the value of the attribute can be modified. By default, this feature is true.
- [[Value]] : Contains the actual value of the property. This is where the aforementioned property values are read and written. The default value of this feature is undefined .
let person = {}
Object.defineProperty(person,'name',{
writable:false,
configurable:false,
value:'Tom'
})
console.log(person.name) // Tom
//这里修改person对象的name值,是无效的,因为上面writable:false,就说明属性的值不可被修改
person.name = 'Jerry'
console.log(person.name) // Tom
//这里删除person对象的name属性,是删除不了的因为上面configurable:false,就说明该属性不能被delete
delete person.name
console.log(person.name) // Tom
Note :
- When calling Object.defineProperty() , if the value of configurable , enumerable and writable is not specified, it will default to false .
- Additionally, once a property is defined as non-configurable (false), it cannot be changed back to configurable. Calling Object.defineProperty() again and modifying any non-writable properties will result in an error
-
There is no way to modify [[Configurable]] or [[Enumerable]] in browsers that don't support Object.defineProperty()
example:
const person = {name:"yd"}
Object.defineProperty(person,"age",{value:21})
person.age = 18
console.log(person) //{name: "jd",age:21}
console.log(Object.keys(person)) // ["name"]
Parse:
When Object.defineProperty() is called , if the values of configurable , enumerable and writable are not specified, they all default to false.
The properties added using the Object.defineProperty method are not enumerable by default , so Object.keys(person)//["name"].
accessor property
- [[Configurable]] : Indicates whether the attribute can be deleted and redefined through delete , whether its characteristics can be modified, and whether it can be changed to a data attribute. By default, this property is true for all properties defined directly on the object .
- [[Enumerable]] : Indicates whether the attribute can be returned by a for-in loop. By default, this property is true for all properties defined directly on the object .
- [[Get]] : Get function, called when the property is read. The default value is undefined .
- [[Set]] : Set function, called when the property is written. The default value is undefined .
Accessor properties cannot be defined directly, Object.defineProperty() must be used .
example:
// 定义一个对象,包含伪私有成员 year_和公共成员 edition
let book = {
year_: 2017,
edition: 1
}
Object.defineProperty(book ,"year",{
get(){
return this.year_
},
set(newVal){
if(newVal > 2017){
this.year_ = newVal
this.edition += newVal - 2017
}
}
})
console.log(book.year) // 2017
book.year = 2018
console.log(book.year) // 2018
console.log(book.edition) // 2
Define multiple properties
let book = {};
Object.defineProperties(book, {
year_: {
value: 2017 ,
// writable:true
},
edition: {
value: 1 ,
// writable:true
},
year: {
get(){
return this.year_;
},
set(newValue){
console.log("1112222222222",newValue)
if (newValue > 2017) {
this.year_ = newValue;
console.log("1112222222222" ,this.year_)
this.edition += newValue - 2017;
}
}
}
})
console.log(book.year_) // 2017
console.log(book.year) // 2017
console.log(book.edition) // 1
//此时这里修改了year 的值 但是打印没变
book.year = 2018
console.log(book.year_) // 2017
console.log(book.year) // 2017
console.log(book.edition) // 1
Notice:
let book = {};
Object.defineProperties(book, {
year_: {
value: 2017 ,
writable:true
},
edition: {
value: 1 ,
writable:true
},
year: {
get(){
return this.year_;
},
set(newValue){
console.log("1112222222222",newValue)
if (newValue > 2017) {
this.year_ = newValue;
console.log("1112222222222" ,this.year_)
this.edition += newValue - 2017;
}
}
}
})
console.log(book.year_) // 2017
console.log(book.year) // 2017
console.log(book.edition) // 1
book.year = 2018
console.log(book.year_) // 2018
console.log(book.year) // 2018
console.log(book.edition) // 1
Read property attributes
Use the Object.getOwnPropertyDescriptor() method to get the property descriptor of the specified property. This method takes two parameters: the object where the attribute resides and the name of the attribute whose descriptor is to be retrieved. The return value is an object
Following the book example above:
let descriptor = Object.getOwnPropertyDescriptor(book, "year_");
console.log(descriptor.value); // 2017
console.log(descriptor.configurable); // false
console.log(typeof descriptor.get); // "undefined"
let descriptor = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor.value); // undefined
console.log(descriptor.enumerable); // false
console.log(typeof descriptor.get); // "function"
ECMAScript 2017 added the Object.getOwnPropertyDescriptors() static method, the return value is an object
Following the book example above:
let descript = Object.getOwnPropertyDescriptors(book)
console.log(descript )
print value:
merge object
- This method receives a target object and one or more source objects as parameters.
- Note: The property copy of Object.assign( ) is a shallow copy
- Same-name attribute replacement, if multiple source objects have the same attribute, the last copied value is used.
let dest ,src, result;
//一个源对象
dest = {}
src = {id:'src'}
result = Object.assign(dest,src)
console.log(result ) // {id:'src'}
//多个源对象
dest = {}
result = Object.assign(dest, { a: 'foo' }, { b: 'bar' });
console.log(result); // { a: foo, b: bar }
// 浅复制体现
dest = {}
src = { a:{b:1}}
result = Object.assign(dest ,src)
console.log(result) // { a:{b:2}} 因为是浅复制,值指向同一位置
console.log(result.a.b) // 1
src.a.b = 2
console.log(result.a.b) // 2
//覆盖属性
dest = {id:'dest'}
result = Object.assign(dest ,{id:'src',a:1},{id:'test',b:2})
console.log(result ) // {id:'test',a:1,b:2}
Object identification and equality determination
- This method is very similar to ===, which is used to compare whether two values are strictly equal.
- This method must receive two parameters
Object.is("q","q"); // true
Object.is(1,1); // true
Object.is([1],[1]); // false
Object.is({q:1},{q:1}); // false
Difference from ===
//一是+0不等于-0
console.log( Object.is(+0,-0) ); //false
console.log( +0 === -0 ) //true
//二是NaN等于本身
console.log ( Object.is(NaN,NaN) ); //true
console.log (NaN === NaN) //false
Enhanced Object Syntax
attribute shorthand
ES6 allows the properties of objects to be directly written to variables. At this time, the property name is the variable name, and the property value is the variable value.
const age = 12;
const name = "Amy";
const person = {age, name};
console.log(person) //{age: 12, name: "Amy"}
//等同于
const person = {age: age, name: name}
Computable properties
const nameKey = 'name';
const ageKey = 'age';
const jobKey = 'job';
let person = {
[nameKey]: 'Matt',
[ageKey]: 27,
[jobKey]: 'Software engineer'
};
console.log(person); // { name: 'Matt', age: 27, job: 'Software engineer' }
Shorthand method name
const person = {
sayHi(){
console.log("Hi");
}
}
person.sayHi(); //"Hi"
//等同于
const person = {
sayHi:function(){
console.log("Hi");
}
}
person.sayHi();//"Hi"
object deconstruction
// 使用对象解构
let person = {
name: 'Matt',
age: 27
};
let { name: personName, age: personAge } = person;
console.log(personName); // Matt
console.log(personAge); // 27
let person = {
name: 'Matt',
age: 27
};
let { name, age } = person;
console.log(name); // Matt
console.log(age); // 27
let personName, personAge;
let person = {
name: 'Matt',
age: 27
};
({name: personName, age: personAge} = person);
console.log(personName, personAge); // Matt, 27