Extending Object Functionality
- Ordinary Objects possess all default internal behaviors of JavaScript objects.
- Exotic Objects possess certain internal behaviors that deviate from the default.
- Standard Objects are objects defined in the ES6 specification, such as Array/Date.
- Built-in Objects are objects that exist in the JavaScript execution environment when the script begins execution; all standard objects are built-in objects.
Object Literal Syntax Extensions
- Shorthand for property initializers: when an object's property has the same name as a local variable, there's no need to write the colon and value.
- Shorthand method syntax for objects.
- Computed property names.
// javascript 引擎会在可访问作用域中查找其同名变量;找到,则该量变的值被赋给对象字面量里的同名属性,在现在的js开发中,为对象字面量的属性赋同名局部变量的值是一种常见的做法,这种简写方法有助于消除命名错误function createPerson(name,age){ return { name, age }}// 对象方法的简写 消除冒号和function关键字。如下var person = { name:"Nicholas", sayName(){ console.log(this.name) }}// 通过对象方法简写语法创建的方法有一个name属性,其值为小括号前的名称,上例中person.sayName()方法的name属性的值为"sayName"In ES5, some property names need to be set and accessed using [] square brackets, for example:
var person = {},lastName = "last name"
person["first name"] = "Nicholas"
person[lastName] = "Zakas"
console.log(person["first name"]); // Nicholas
console.log(person[lastName]); //Zakas
Because property names contain spaces, they cannot be referenced using dot notation, but square brackets can be used as they support accessing property values using any string value as the name.
Within object literals, string literals can be used directly as property names, as shown below:
var person = {
"first name": "Nicholas"
}
console.log(person["first name"]); // "Nicholas"
// Es5 无法为通过计算得到的变量值,作为对象的字面量定义该属性
// es6 通过中括号方式可以定义这样的字面量
let lastName = "last name";
let person = {
"first name": "Nicholas",
[lastName]:"Zakas"
}
console.log(person["first name"]); // Nicholas
console.log(person[lastName]); // Zakas
console.log(person["last name"]) // Zakas
Object.is()
This method compensates for the inaccuracies of the strict equality operator. It accepts two arguments; if both arguments are of the same type and have the same value, it returns true.
Object.is(NaN,NaN) // true
NaN === Nan //false
console.log(+0==-0) //true
console.log(+0===-0) //true
console.log(Object.is(+0,-0)) //false
console.log(NaN==NaN) //false
console.log(NaN==NaN) //true
console.log(Object.is(NaN,Nan)) //true
console.log(Object.is(5,5)) //true
console.log(Object.is(5,"5")) //false
Object.assign()
Mixin is one of the most popular patterns for achieving object composition in JavaScript. In a mixin method, one object receives properties and methods from another object. Many JavaScript libraries have similar mixin methods:
// 浅复制
function minxin(receiver, supplier){
Object.keys(supplier).forEach(function(key){
receiver[key] = supplier[key]
})
return receiver
}
The Object.assign() method achieves the same functionality. This method accepts a target object and any number of source objects. The mixin() method uses the assignment operator = to copy relevant properties, but it cannot copy accessor properties to the target object. Therefore, the ultimately added method deprecates mixin and uses assign as the method name.
The Object.assign() method can accept any number of source objects and copies properties to the target object in the specified order. If multiple source objects have properties with the same name, the properties from later source objects will overwrite those from earlier ones.
The
Object.assign()method cannot copy accessor properties from a source object to a target object. Because Object.assign() performs an assignment operation, an accessor property from the source will ultimately be converted into a data property in the target object.
var receiver = {},supplier = {
get name() {
return "file.js"
}
};
Object.assign(receiver,supplier);
var descriptor = Object.getOwnPropertyDescriptior(receiver,"name")
console.log(descriptor.value); //file.js
console.log(descriptor.get); // undefined
Duplicate Object Literal Properties
In ES5, duplicate property names would cause an error. ES6 no longer enforces this strict constraint; for each set of duplicate properties, the last value assigned will be taken.
Own Property Enumeration Order
ES6 strictly defines the return order when an object's own properties are enumerated. This affects how Object.getOwnPropertyNames() and Reflect.ownKeys return properties, and the order in which Object.assign() processes properties will also change. The rules are as follows:
- All numeric keys are sorted in ascending order.
- All string keys are sorted in the order they were added to the object.
- All symbol keys are sorted in the order they were added to the object.
Enhancing Object Prototypes
ES5 is one of the most important settings in JavaScript programming. Although the Object.getPrototypeOf() method was added in ES5 to return the prototype of any object, a standard method to change an object's prototype after instantiation was still missing. ES6 introduced the Object.setPrototypeOf() method to change this situation. This method allows you to change the prototype of any specified object, and it accepts two arguments: the object whose prototype is to be changed, and the object that will replace the first argument's prototype.
let person={
getGreeting(){
return "Hello";
}
}
let dog = {
getGreeting(){
return "Woof";
}
}
// 以person对象为原型
let friend = Ojbect.create(person);
console.log(friend.getGreeting()); // Hello
console.log(Object.getPrototypeOf(friend) === person) // true
// 将原型设置为dog
Object.setPrototypeOf(friend,dog);
console.log(friend.getGreeting()) // Woof
console.log(Object.getPrototypeOf(friend)===dog) // true
The true value of an object's prototype is stored in the internal special property [[Prototype]]. Calling Object.getPrototypeOf() returns the value stored there, and calling Ojbect.setPrototypeOf() changes that value. However, this is not the only way to manipulate the [[Prototype]] value.
- We need to remember two points: ① The
__proto__andconstructorproperties are unique to objects; ② Theprototypeproperty is unique to functions, but since functions are also objects, they also possess__proto__andconstructorproperties. - The purpose of the
__proto__property is that when accessing a property of an object, if that property does not exist within the object itself, it will look in the object (parent object) pointed to by its__proto__property, and continue searching until the end of the__proto__chain, which is null. Searching further up from null is equivalent to accessing a value on null, which will cause an error. This chain that connects objects via the__proto__property is what we call the prototype chain. - The purpose of the
prototypeproperty is to allow objects instantiated by that function to find common properties and methods, i.e.,f1.__proto__ === Foo.prototype. - The meaning of the
constructorproperty is to point to the constructor function of that object. All functions (when viewed as objects) ultimately have their constructor pointing to Function.
The Role of Super in Simplifying Prototype Access
Subclass methods override parent class methods and also need to call and pass arguments to parent class methods; ECMAScript 6 introduced the Super reference feature, which allows for more convenient access to object prototypes.
let person={
getGreeting(){
return "Hello";
}
}
let dog = {
getGreeting(){
return "Woof";
}
}
let friend = {
getGreeting(){
return Object.getPrototypeOf(this).getGreeting.call(this)+', hi!'
}
}
// 以person对象为原型
Object.setPrototypeOf(friend,person)
console.log(friend.getGreeting()); // Hello,hi!
console.log(Object.getPrototypeOf(friend) === person) // true
// 将原型设置为dog
Object.setPrototypeOf(friend,dog);
console.log(friend.getGreeting()) // Woof,hi!
console.log(Object.getPrototypeOf(friend)===dog) // true
ES6 simplifies this syntax:
let friend = {
getGreeting(){
// return Object.getPrototypeOf(this).getGreeting.call(this)+', hi!'
return super.getGreeting()+", hi~"
}
}
// 注意要使用简写方法对象中使用super引用,如下会报错
let friend = {
getGreeting:function(){
// return Object.getPrototypeOf(this).getGreeting.call(this)+', hi!'
return super.getGreeting()+", hi~"
}
}
The
superreference is not dynamic; it always points to the correct object. In this example, no matter how many other methods inherit the getGreeting method, super.getGreeting() always points to
Formal Method Definitions
In ES6, a method is formally defined as a function that will have an internal [[HomeObject]] property to hold the object to which this method belongs. As follows:
let person = {
// 这是方法
getGreeting(){
return "Hello"
}
};
// 不是方法
function shareGreeting(){
return "Hi~";
}
Understanding: In this example, a person object is defined, which has a getGreeting() method. Since the function is directly assigned to the person object, the [[HomeObject]] property of the getGreeting() method is person. However, the shareGreeting method below was not assigned to an object when created, and thus this method does not have a clearly defined [[HomeObject]] property. In most cases, this small difference is irrelevant, but it becomes very important when using Super references.
All super references determine their subsequent execution process through the [[HomeObject]] property. The first step is to call Object.getPrototypeOf() on the [[HomeObject]] property to retrieve the prototype reference; then, the prototype is searched to find a function with the same name, and finally, the this binding is set, and the corresponding method is called.
// 自己分析一下
let person={
getGreeting(){
return "Hello";
}
}
let friend = {
getGreeting(){
// return Object.getPrototypeOf(this).getGreeting.call(this)+', hi!'
return super.getGreeting()+", hi~"
}
}
Object.setPrototypeOf(friend,person)
console.log(friend.getGreeting()) // "Hello hi~"
Summary
- Properties
- Simplified property definition syntax, making the syntax for assigning a variable with the same name from the current scope to an object more concise;
- Added computed property names feature, allowing non-literal property names to be specified for objects;
- Added shorthand method syntax for objects, allowing the colon and function keyword to be omitted when defining methods in object literals.
- ES6 strict mode object literal duplicate name validation: even if two properties with the same name are defined in the same object literal, no error will be thrown.
- The
Object.assign()method can change multiple properties in an object at once, which is very useful when using the mixin pattern. - The
Object.is()method performs strict equality comparison for all values, making it safer than===when dealing with JavaScript value issues. - The
Object.setPrototypeOf()method, which modifies an object's prototype after it has been created. - The
superkeyword calls methods on the prototype, and the this binding is automatically set to the this value of the current scope.
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/4329
