Prototype chain basic concept

  • function Func(){} ; let f1 = new Func()
  • The __proto__ and constructor attributes are unique to the object;
  • The Prototype property is function specific and points from the function to the object
  • But since functions in JS are also objects, they also have __proto__ and constructor attributes
object function
__proto__ There are There are
prototype There is no There are
constructor There are There are
  • One thing to keep in mind is that only constructors have a. Prototype property, and objects don’t have that property,
  • __proto__ is just one of the nonstandardized ways that browsers provide access to the prototype Object’s constructor. In fact, it’s more standard to use object.getProtoTypeof (a) to get the prototype Object of an Object because the Object has no prototype. A. __proto__. Prototype is actually retrieved
  • For instance, a constructor call User (the same Array, String, Boolean, Regexp, Object), create a User Object, he will be automatically assigned their own prototype for use in the User
  • __proto__ can both set and get. This is not the standard format for browsers to support. Use the formal format below
    • Object.setPrototypeOf(user,parent)
    • Object.getPrototypeOf(user)
  • Custom object prototype setup, concept of inheritance
    • User.__proto__ = parent is not recommended
    • Object. SetPrototypeOf (user,parent)
  • User instanceOf user. A looks for B on the prototype chain
  • User.prototype.isPrototypeOf(user) \
  • In and hasOwnProperty
    • In checks the prototype chain
    • HasOwnProperty only looks at the current object
    • So some for loops automatically add hasOwnProperty judgment
      • for(const key in a){
      • if(Object.hasOwnProperty(key)){…… }}
  • Borrow other people’s methods
    • Afunction.Aprototype.call(null/thisB,Bpram1,Bpram2…) The list of parameters
    • Afunction. Aprototype. Applay (null/Bthis, [Bparams]) parameters of the array
  • Object.create(obj)
    • Obj creates a new object for the prototype
    • User.prototype = Object.create(Parent.prototype)
  • Inheritance of stereotypes, rather than changing the stereotype of the constructor
    • child.prototype.__proto__= father.prototype
  • Object to write

let obj = { name:’shist’, get getName(){…. } set setName(vname){if(xxxx){this.name = vname}} }

  • Class concept

/ / the original writing

function User(name){ this.name = name this.show = function(){ console.log(name) } } let a = new User('a')//User {name: "A", show: ƒ} let b = new User (' b ') / / User {name: "b", show: ƒ}Copy the code

// Since the same show method is used, there is no need to write a separate one to increase memory overhead, can be put in the prototype

function User(name){ this.name=name } User.prototype.show=function(){ console.log(this.name) } let a = new //User {name: "a"} let b = new User('b')//User {name: "b"} can call show() from prototypeCopy the code

// improve if multiple methods

User.prototype = {
  constructor:User,
    show(){console.log('show name')},
    buy(){consoe.log('buy ...')}
}
Copy the code

Summary of common object methods

Object.assign(target,source1,source2,…)

This method is mainly used to merge objects. All the enumerable attributes of the source object are merged into the target object. This method only copies the attributes of the source object, not the inherited attributes.

The object. assign method implements shallow copy, not deep copy. That is, if the value of an attribute of the source object is an object, the target object copies a reference to that object. Properties of the same name are replaced. Object.assign can only be used to copy values. If the value to be copied is a value function, it will be evaluated and then copied. Object.assign works with arrays, but treats arrays as objects.

x : 0, y : 1 }; const source = { x : 1, z : 2 , fn : { number : 1 } }; Object.assign(target, source); // target {x: 1, y: 1, z: 2, fn: {number: 1}} 1}} target.fn.number = 2; Function Person(){this.name = 1}; Person.prototype.country = 'china'; let student = new Person(); student.age = 29 ; const young = {insterst : 'sport'}; Object.assign(young,student); // young {instest : 'sport' , age : 29, name: Prototype Object.assign([1, 2, 3], [4, 5]); //Copy the code

Object.create(prototype[,propertiesObject])

Creates a new object using the specified prototype object and its properties

X: 1, y: 1} var child = Object. The create (parent, {z: {/ / z attributes of the Object will be created writable: true, configurable: true, value: "newAdd" } }); console.log(child) Object.defineProperties(obj,props)Copy the code

Defines new properties or modifies existing properties directly on an object and returns the object.

Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});
console.log(obj)   // {property1: true, property2: "Hello"}
Copy the code

Object.defineProperty(obj,prop,descriptor)

Define a new property on an object, or modify an existing property of an object, and return the object.

DefineProperty (Object, 'is', {value: function(x, y) {if (x === y) {return x! == 0 || 1 / x === 1 / y; } // For NaN, return x! == x && y ! == y; }, configurable: true, enumerable: false, writable: true }); // Do not set the (writable, value) and get, set methods at the same time.  Invalid property descriptor. Cannot both specify accessors and a value or writable attributeCopy the code

Object.keys(obj)

Returns an array of the self-enumerable properties of a given object, in the order of the property names and using the for… The in loop returns the same order as it iterates through the object (the main difference between the two is that a for-In loop also enumerates the properties on its prototype chain).

let arr = ["a", "b", "c"]; console.log(Object.keys(arr)); / / [' 0 ', '1', '2'] / * * / Object Object obj = {foo: "bar", baz: 42}, keys = Object. The keys (obj); console.log(keys); // ["foo","baz"]Copy the code

Object.values()

Method returns an array of all the enumerable property values of a given object, in the same order as using the for… The in loop has the same order (the difference is that for-In loops enumerate properties in the stereotype chain). Object.values filters properties with the property name Symbol value.

var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']
 
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']
Copy the code

Object.entries()

Returns an array of key-value pairs for the given object’s own enumerable properties, arranged in the same way as for… The in loop returns the same order as it iterates through the object (the difference is that for-In loops also enumerate properties in the prototype chain).

const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
 
const simuArray = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(simuArray)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
Copy the code

hasOwnProperty()

Checks whether the object has the specified attribute in its own attributes. obj.hasOwnProperty(‘name’)

Object.getOwnPropertyDescriptor(obj,prop)

Returns the property descriptor corresponding to a property of its own on the specified object. (Own properties refer to properties that are directly assigned to the object and do not need to be looked up on the stereotype chain). Returns the property descriptor object if the specified property exists on the object, otherwise undefined.

var arr = ['name','age'] ;
arr.forEach(val => console.log(Object.getOwnPropertyDescriptor(obj,val)))
 
 
// {value: "js", writable: true, enumerable: true, configurable: true}
// undefined

 
 Object.getOwnPropertyDescriptors(obj)
Copy the code

Gets the descriptor for all of an object’s own properties.

var obj = {
    name : 'js',
    age : 20
}
console.log(Object.getOwnPropertyDescriptors(obj))
Copy the code
const source = { set foo(value) { console.log(value); }}; const target2 = {}; Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source)); Object.getOwnPropertyDescriptor(target2, 'foo') const obj = Object.create( some_obj, Object.getOwnPropertyDescriptors({ foo: 123, }) );Copy the code

Object.getOwnPropertyNames()

Returns an array of the property names of all of the object’s own properties, including properties that are not enumerable but do not include the Symbol value as a name.

var obj = { 0: "a", 1: "b", 2: "c"}; Object.getOwnPropertyNames(obj).forEach(function(val) { console.log(val); }); var obj = { x : 1, y : 2 } Object.defineProperty(obj,'z',{ enumerable : False}) console. The log (Object. GetOwnPropertyNames (obj)) / / [" x ", "y", "z"] contains an enumeration properties. Console. log(object.keys (obj)) // ["x", "y"] contains only enumerable properties.Copy the code

Object.getOwnPropertySymbols()

Returns an array of all Symbol properties for a given object itself.

Object.getPrototypeOf()

Returns the Prototype of the specified object (the value of the internal [[Prototype]] property, that is, __proto__, not the Prototype of the object).

isPrototypeOf()

Determines whether an object exists on the prototype chain of another object.

Object.setPrototypeOf(obj,prototype)

Sets the prototype object of the object

Object.is()

Determine whether two values are the same.

If either of the following is true, the two values are the same:

  • Both values are undefined
  • Both values are null
  • Both values are true or both are false
  • Two values are strings of the same number of characters in the same order
  • Both values refer to the same object
  • Both values are numbers and
    • They’re both positive zero plus zero
    • They’re all negative zero minus zero
    • Is NaN
    • All the same numbers except zero and NaN
Object.is('foo', 'foo'); // true Object.is(window, window); // true Object.is('foo', 'bar'); // false Object.is([], []); // false var test = { a: 1 }; Object.is(test, test); // true Object.is(null, null); // true // object.is (0, -0); // false Object.is(-0, -0); // true Object.is(NaN, 0/0); // trueCopy the code

Object.freeze()

To freeze an object, you cannot add new attributes to the object, modify the values of existing attributes, delete existing attributes, and modify the enumerability, configurability, and writability of existing attributes of the object. That is, the object is always immutable. This method returns the frozen object.

var obj = { prop: function() {}, foo: 'bar' }; // New attributes will be added, existing attributes may // be modified or removed obj.foo = 'baz'; obj.lumpy = 'woof'; delete obj.prop; Var o = object.freeze (obj); var o = object.freeze (obj); o === obj; // true Object.isFrozen(obj); // now any changes will be invalid obj.foo = 'quux'; Obj. Quaxxor = 'the friendly duck'; console.log(obj)Copy the code

Object.isFrozen()

Determines whether an object is frozen.

Object.preventExtensions()

Object cannot add new attributes. Can be modified, delete existing attributes, cannot add new attributes.

var obj = {
    name :'lilei',
    age : 30 ,
    sex : 'male'
}
 
obj = Object.preventExtensions(obj);
console.log(obj);    // {name: "lilei", age: 30, sex: "male"}
obj.name = 'haha';
console.log(obj)     // {name: "haha", age: 30, sex: "male"}
delete obj.sex ;
console.log(obj);    // {name: "haha", age: 30}
obj.address  = 'china';
console.log(obj)     // {name: "haha", age: 30}
Copy the code

Object.isExtensible()

The Object.preventExtensions, Object.seal, or Object.freeze methods can all mark an Object as non-extensible.

Object.seal()

The object.seal () method seals an Object and returns the sealed Object. Sealing an object makes it impossible to add new properties, and all existing properties become unconfigurable. The effect of a property not being configurable is that the property becomes non-deletable, and a data property cannot be redefined as an accessor property, or vice versa. However, the value of the attribute can still be modified. Attempts to delete a property of a sealed object or to convert a property of a sealed object from a data property to an accessor property result in a silent failure or A TypeError exception. Attributes inherited from the stereotype chain are not affected. But the value of the proto () property cannot be changed either.

var obj = { prop: function () {}, foo: "bar" }; Obj. Foo = "baz"; obj.lumpy = "woof"; delete obj.prop; var o = Object.seal(obj); assert(o === obj); assert(Object.isSealed(obj) === true); Obj. foo = "quux"; // You can still change the values of attributes on the sealed object. // But you cannot redefine a data attribute as an accessor attribute. Object.defineProperty(obj, "foo", { get: function() { return "g"; }}); // Raise TypeError // Now, any modification beyond the value of the attribute will fail. // Silence failed, the new property did not add delete obj.foo successfully; // Silence failed, attribute not deleted successfully //... In strict mode, TypeError is raised. Function fail() {"use strict"; delete obj.foo; // Raise TypeError obj.sparky = "arf"; // Raise TypeError} fail(); DefineProperty (obj, "ohai", {value: 17}); // Throws TypeError object.defineProperty (obj, "foo", {value: "eit"}); // Successfully change the original valueCopy the code

Object.isSealed()

Determines whether an object is sealed

Reference: bilibili prototype on www.bilibili.com/video/BV17J… Help you understand prototype, __proto__ and constructor thoroughly