In-depth Understanding of ES6 004 [Study Notes]

Extending object functionality
Ordinary objects: objects that possess all default internal behaviors of a JavaScript object.
Exotic objects: objects that possess certain internal behaviors that deviate from the default.
Standard objects: objects defined in the ES6 specification, such as Array/Date.
Built-in objects: 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 syntax for object methods...

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.

prototype

  1. We need to remember two points: ① The __proto__ and constructor properties are unique to objects; ② The prototype property is unique to functions, but since functions are also objects, they also possess __proto__ and constructor properties.
  2. 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.
  3. The purpose of the prototype property is to allow objects instantiated by that function to find common properties and methods, i.e., f1.__proto__ === Foo.prototype.
  4. The meaning of the constructor property 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 super reference 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 super keyword 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

(0)
Walker的头像Walker
上一篇 Mar 8, 2025 12:51
下一篇 Mar 8, 2025 10:59

Related Posts

  • Go Engineering Systematic Course 003 [Study Notes]

    grpc grpc grpc-go grpc seamlessly integrates protobuf protobuf. For those of you accustomed to using JSON and XML data storage formats, I believe most have never heard of Protocol Buffer. Protocol Buffer is actually a lightweight & efficient structured data storage format developed by Google, and its performance is truly much, much stronger than JSON and XML! protobuf…

    Personal Nov 25, 2025
    18800
  • Go Engineer's Comprehensive Course 017: Learning Notes

    Introduction to Rate Limiting, Circuit Breaking, and Degradation (with Sentinel Practical Application)
    Based on the key video points from Chapter 3 (3-1 to 3-9) of the courseware, this guide compiles a service protection introduction for beginners, helping them understand "why rate limiting, circuit breaking, and degradation are needed," and how to quickly get started with Sentinel.
    Learning Path at a Glance
    3-1 Understanding Service Avalanche and the Background of Rate Limiting, Circuit Breaking, and Degradation
    3-2 Comparing Sentinel and Hystrix to clarify technology selection
    3-3 Sen...

    Personal Nov 25, 2025
    18000
  • Node: In-depth Yet Accessible (Sheng Siyuan Education) 001 [Study Notes]

    Node.js: Understanding it from an Asynchronous Programming Paradigm
    Node.js's Positioning and Core Philosophy
    Based on the V8 engine + libuv event-driven library, it brings JavaScript from the browser to the server side. It uses a single-threaded event loop to handle I/O, maximizing CPU time slices while waiting for I/O, making it particularly suitable for high-concurrency, I/O-intensive scenarios. "Don't block the main thread" is its design philosophy: try to offload time-consuming operations to the kernel or a thread pool, and callback results...

    Personal Nov 24, 2025
    28100
  • In-depth Understanding of ES6 011 [Learning Notes]

    Promises and Asynchronous Programming

    Because the execution engine is single-threaded, it needs to track the code that is about to run. This code is placed in a task queue. Whenever a piece of code is ready to execute, it is added to the task queue, and whenever a piece of code in the engine finishes execution, the event loop executes the next task in the queue. A Promise acts as a placeholder for the result of an asynchronous operation. It doesn't subscribe to an event or pass a callback function to the target function. Instead, it allows the function to return a Promise, like this...

    Personal Mar 8, 2025
    1.1K00
  • Node In-depth and Easy to Understand (Sheng Siyuan Education) 002 [Study Notes]

    Node's package management and loading mechanisms: npm search xxx, npm view xxx, npm install xxx. Node.js file system operation APIs: Node.js's `fs` module provides synchronous (Sync) and callback/Promise-based asynchronous APIs for operating on local files and directories. Commonly used capabilities in daily development include reading, writing, appending, deleting, traversing directories, listening for changes, and so on. The following examples are based on C...

    Personal Nov 24, 2025
    23100
EN
简体中文 繁體中文 English
欢迎🌹 Coding never stops, keep learning! 💡💻 光临🌹