Object-oriented JavaScript

Source: Internet
Author: User
Tags instance method object object shallow copy wrapper hasownproperty

Object of JavaScript

An object is a data type of JavaScript. An object can be considered an unordered collection of attributes, each of which is a key-value pair, and the property name is a string, so the object can be treated as a string-to-value mapping. This data structure is referred to in other languages as hash (hash), Dictionary (dictionary), associative array (associative array), and so on.

Prototype inheritance: objects are not just string-to-value mappings, but, in addition to preserving their own properties, JavaScript objects can inherit properties from an object called a prototype, which is typically inherited properties, which is the core feature of JavaScript.

JavaScript objects are dynamic-you can add properties or delete properties, but they are often used to simulate "structs" in static and statically typed languages

Creating objects

1. Direct volume of objects

The simplest way to create an object is to use the direct amount of the object in JavaScript code.

var book = {            "main title": 'guide',  //属性名字里有空格,必须加引号            "sub-title": 'JS',  //属性名字里有连字符,必须加引号            for: 'development',  //for是关键字,不过从ES5开始,作为属性名关键字和保留字可以不加引号            author: {                firstname: 'David',  //这里的属性名就都没有引号                surname: 'Flanagan'            }        }

Note: Starting with ES5, the comma after the last attribute in the object's direct volume is ignored.

Extensions: [keywords and reserved words in JavaScript]

2. Create an object from new

The new operator creates and initializes an object. The keyword new is followed by a function call. The function here is called the constructor (constructor), and the constructor is used to initialize a newly created object. The data types in JavaScript contain built-in constructors.

var o = new Object(); //创建一个空对象,和{}一样。 var arr = new Array(); //创建一个空数组,和[]一样。
Extended 1:new

New is a unary operator, which is a specialized arithmetic function. A function called after new is called a constructor, and the process of constructor new is called instantiation.
When new goes to invoke a function: this time in the function will point to the created object, and the return value of the function is directly this (implicit return)
One default convention is to capitalize the first letter of the constructor.

Attention:
When return, if it is followed by a simple type, then the return value is the object;
If return is an object type, then return is the object that follows return.

Extension 2: Differences between base types and object types (complex types)

Assignment value:
Base type: value is only copied when assigned
Object type: Assignment is not only a copy of a value, but also a reference pass (which can be understood as a memory address) that can be understood as an assignment.

Compare equal
Basic type: The same value can be
Object type: Both values and references are the same.

Extension 3: Prototype prototype

Each JavaScript object (except NULL) is associated with another object, which is a prototype, and each object inherits properties from the prototype.

3, Object.create ()

Object.create () This method is defined by ES5, which creates a new object, where the first parameter is the prototype of the object. The second parameter is an optional parameter that is used to further describe the properties of an object.

You can create a new object without a prototype by passing in the parameter null, but the new object does not inherit anything, not even the underlying method.
var o = object.create (null); O does not inherit any properties and methods, empty.

If you want to create a normal empty object, you need to pass in Object.prototype
var o = object.create (object.prototype); O equals {}

Getting and setting object properties

You can pass the dot (.) or the square brackets ([]) operator to get and set the value of the property.

var author = book.author;var title = book["main title"];

Can be used in JavaScript. Connections can be connected using []. There are many. When the operator is not available, you need to replace it with [].
1, in the case of variable attribute name with []

function getAttr (obj, attr) {    console.log(obj[attr])}

2, the attribute name has the space or the hyphen and so on uses []

var title = book["main title"];
Delete Property

The delete operator can delete an object's properties.
Delete simply disconnects the property from the host object and does not manipulate the properties in the property, and if the deleted property is an object, then the reference to the object is still present.

var a = {b:{c:1}};var b = a.b;console.log(b.c); // 1console.log(a.b); // {c:1}delete a.b;console.log(b.c); // 1console.log(a.b); //undefined

Delete can only delete its own property and cannot delete the inherited property.

return value

The return value is True

Delete returns True when delete expression succeeds or has no side effects (such as deleting a nonexistent property), or after delete is not a property access expression;

var a = {b:{c:1}};console.log(delete a.b);console.log(delete a.b);console.log(delete a.toString);console.log(delete 1);以上都会打印true
The return value is False

Delete cannot delete properties that are configurable as false, such as properties of some built-in objects that are not configurable, properties of global objects created through variable declarations and function declarations.

var a = {};Object.defineProperty(a,'b',{    value:1,    configurable: false // 设置为不可配置})console.log(delete a.b)console.log(delete Object.prototype)var x = 1;console.log(delete this.x);console.log(delete x)以上打印都为false
Detection properties

In operator

The left side of the in operator is the property name (string) and the right side is the object. Returns true if this property is included in the object's own property or inheritance property.

var a = {b:1};console.log('a' in window); // true 声明的全局变量'a'是window的属性console.log('b' in a); // true 'b'是a的属性console.log('toString' in a); // true a继承了toString属性console.log('c' in a); // false 'c'不是a的属性

Similar to the in operator, you can also use "!==" to determine whether a property is undefined, but there is a scenario where you can use the in operator only, in to distinguish between nonexistent and existing properties that have a value of undefined.

var a = {b:undefined};console.log(a.b !== undefined); //falseconsole.log(a.c !== undefined); //falseconsole.log('b' in a); //trueconsole.log('c' in a); //false

hasOwnProperty

The hasOwnProperty () method of an object is used to detect whether a given name is an object's own property. For inherited properties it will return false

var a = {b:1};console.log(a.hasOwnProperty('b')); //trueconsole.log(a.hasOwnProperty('c')); //falseconsole.log(a.hasOwnProperty('toString')); //false toString是继承属性

propertyIsEnumerable

The propertyIsEnumerable () method of an object returns true only if it detects that it is its own property (excluding inherited properties) and that the property has an enumerable of true.

var a = {b:1};console.log(a.propertyIsEnumerable('b'));console.log(a.propertyIsEnumerable('toString'));
Wrapping Object

When a value of the original type (string, number, Boolean) is used, the interior is automatically converted to the corresponding object when the corresponding property and method are called. This object is implicitly created and becomes the wrapper object.
Basic types have their own corresponding wrapper objects: String number Boolean

Wrapper object Characteristics After you create an object implicitly, you can call the corresponding property and method to destroy it immediately after use, so you cannot add properties and methods to the value of the original type

Examples of the process: str.substring-> New String (1234)-> Find string substring, destroy new string

Summary of Object methods and properties

Object static method

    • Object.assign ()
    • Object.create ()
    • Object.defineproperty ()
    • Object.defineproperties ()
    • Object.entries ()
    • Object.preventextensions ()
    • Object.isextensible ()
    • Object.seal ()
    • Object.issealed ()
    • Object.freeze ()
    • Object.isfrozen ()
    • Object.keys ()
    • Object.values ()
    • Object.getprototypeof ()
    • Object.getownpropertynames ()
    • Object.getownpropertydescriptor ()
    • Object.getownpropertydescriptors ()

instance method of object (defined on Object.prototype)


    • Object.prototype.hasOwnProperty ()

    • Object.prototype.isPrototypeOf ()

    • Object.prototype.propertyIsEnumerable ()

    • Object.prototype.toString ()

    • Object.prototype.valueOf ()

The idea of object-oriented coding

Two ways of programming:
(1), process-oriented
(2), Object-oriented

The difference between the two:
Process oriented: Focus on the implementation process and the implementation details of each step.
Object-oriented: Focus on features and functionality.

Object-Oriented Programming

The popular point, the object of the idea of writing code is object-oriented programming.

Basic Features

1, Abstract: Grasp the core problem (simple understanding of the part of the extract image, the same or performance and problem-related characteristics of the content extracted. )
Its core: extracting, extracting, and extracting the same pieces of code (which may be maintainable, iterative, expanding) to form a class

2, encapsulation: is to wrap the properties of the class, do not let the outside world easily know its internal implementation; Only external interfaces are provided for invocation

3. Inherit: Inherit new object from existing object

4. Polymorphism: Different forms of an object

Object-oriented Benefits

1. Clearer hierarchy of code
2, more easy to reuse
3, more easy to maintain
4, more easy to expand

Object-oriented related properties and concepts

The
__proto__ attribute prototype chain, the connection between the instance object and the prototype, is called the prototype chain.

Only the proto constructor on the object is prototype and Proto .

Constructor returns a reference to the constructor that created the instance object, and each prototype automatically adds the constructor property, for: In.. This property cannot be found by traversing the prototype.
var a = new A();console.log(a.constructor == A) //true
hasOwnProperty can be used to determine whether a property is an intrinsic property of this constructor (not including inherited)

Syntax: Obj.hasownproperty (Prop) returns a Boolean

function A (){    this.b = 1;}var a = new A();console.log(a.hasOwnProperty('b'));  //打印true console.log(a.hasOwnProperty('toString')); //toString是继承属性 打印 falseconsole.log(a.hasOwnProperty('hasOwnProperty')); //同上,打印false
The
nstanceof two-tuple operator is used to detect whether an object has a prototype property of a constructor in its prototype chain.

Syntax: Object instanceof Constructor detects if the Constructor.prototype exists on the prototype chain of the Parameter object.

// 定义构造函数function C(){} function D(){} var o = new C();o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototypeo instanceof D; // false,因为 D.prototype不在o的原型链上o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回trueC.prototype instanceof Object // true,同上
ToString Returns a String representing the object

Role:
1, the conversion between the number of the binary

例如:var num = 255;alert( num.toString(16) ); //结果就是'ff'

2, the use of ToString to make the type of judgment

例如:var arr = [];alert( Object.prototype.toString.call(arr) == '[object Array]' );     弹出trueObject.prototype.toString.call()    得到是类似于'[object Array]'  '[object Object]'
The process of object-oriented writing

1. Original mode

If we have an object that is a prototype of a dog, this prototype has two attributes of "name" and "Color".

var Dog = {
Name: ",
Color: '
}
Based on this prototype object, we are going to generate an instance object as follows

var hashiqi = {}; //创建空对象,之后根据原型对象的相应属性赋值hashiqi.name = 'hashiqi';hashiqi.color = 'blackandwhite';

Disadvantages:
1. If you want to generate multiple instance objects, repeat the write multiple times.
2. There is no connection between the instance and the prototype.

2. Factory mode

One drawback of the original schema above is that it is cumbersome to write a lot of repetitive code, and we can write a function to solve the problem of code duplication.

function Dog(name, color) {    var obj = {};    obj.name = name;    obj.color = color;    return obj;}var hashiqi = Dog('hashiqi', 'blackandwhite');var jinmao = Dog('jinmao', 'yellow');

This approach only solves the problem of code duplication, but the generated instances are still not linked to the prototype, and Hashiqi and Jinmao are not linked, and cannot reflect that they are instances of the same prototype object.

3. Constructor mode

The function used to create the object, called the constructor, is actually a normal function, but the default function name is capitalized, and the new operator is used on the constructor to generate the instance, and the this variable is bound to the instance object.

function Dog(name, color) {    this.name = name;    this.color = color;}var hashiqi = new Dog('hashiqi', 'blackandwhite');var jinmao = new Dog('jinmao', 'yellow');console.log(hashiqi.name); //hashiqiconsole.log(jinmao.name); //jinmao

Hasiqi and Jinmao have a common constructor hashiqi.constructor = = = Jinmao.constructor is True

There are several ways to validate the relationship between a prototype object and an instance object:

hashiqi instanceof Dog; // trueObject.getPrototypeOf(hashiqi) === Dog.prototype // trueDog.prototype.isPrototypeOf(hashiqi) // true

Disadvantages:
The constructor solves the code duplication and the connection between the instance and the prototype, but there is a memory-wasting problem. For example, a travel object has some invariant properties and a common method, so that no instance is generated, it must have more memory for the duplicated things.

Extended

We can try to implement the logic of the new operator as follows:

function New(func) {    var obj = {};    //判断构造函数是否存在原型,如果有实例的__proto__属性就指向构造函数的prototype    if(func.prototype !== undefined) {        obj.__proto__ = func.prototype;    }    // 模拟出构造函数内部this指向实例的过程,注意,我们会拿到构造函数的返回值    var res = func.apply(obj, Array.from(arguments).slice(1));    // 正常构造函数是不需要显式声明返回值的,默认的返回值是生成的实例,但是一旦在构造函数中return 一个不是对象或者函数,就会改变构造函数的默认的返回值,其他的类型是不变的    if(typeof res === 'object' && res !== null || typeof res === 'function') {        return res;    }    return obj;}var taidi = New(Dog, 'taidi', 'gray');

Attention:
The normal constructor does not need to write the return itself, if it is written, when return, if it is followed by a simple type, then the return value is the constructor generated by the instance. If return is an object type or function, then return is the object or function that follows return.

4. Prototype mode

Each constructor has a prototype attribute, which points to an object that all properties and methods of the object are inherited by an instance of the constructor.
Based on this attribute, we can selectively define some common properties and methods on prototype, and each instance generated by new will have a proto attribute to the constructor's prototype, namely prototype, This way we define the properties and methods of the constructor prototype object, which is accessed by each instance, and becomes a common property and method.

function Dog(name, color) {    this.name = name;    this.color = color;}Dog.prototype.say = function () {    console.log("汪汪");}var hashiqi = new Dog('hashiqi', 'blackandwhite');var jinmao = new Dog('jinmao', 'yellow');hashiqi.say(); // 汪汪jinmao.say(); // 汪汪console.log(hashiqi.say === jinmao.say); // true

Note: When an instance object and a prototype object have the same properties or methods, the properties or methods of the instance object are given priority access.

Object-Oriented inheritance

1. Property and method inheritance inside the constructor

Use the call or Apply method to bind the parent object's constructor to the child object.

//父类function Animal() {    this.species = '动物';}//子类function Dog(name, color) {    Animal.call(this);    this.name = name;    this.color = color;}var hashiqi = new Dog('hashiqi', 'blackandwhite');console.log(hashiqi.species); //动物

2. Inheritance related to prototype

the prototype of the child class points to the parent class generation instance
function Animal() {};Animal.prototype.species = '动物';function Dog(name, color) {    this.name = name;    this.color = color;}Dog.prototype = new Animal();//只要是prototype被完全覆盖,都得重写constructor。Dog.prototype.constructor = Dog;var hashiqi = new Dog('hashiqi', 'blackandwhite');

Disadvantage: Each inheritance has to generate a parent class instance, which compares the memory.

using an empty object as an intermediary
function Animal() {}Animal.prototype.species = '动物';function Dog(name, color) {    this.name = name;    this.color = color;}//Middle生成的是空实例(除了__proto__),几乎不占内存function Middle() {}Middle.prototype = Animal.prototype;Dog.prototype = new Middle();Dog.prototype.constructor = Dog;var hashiqi = new Dog('hashiqi', 'blackandwhite');console.log(hashiqi.species);

A few months ago in CSDN interview, I said this way of inheritance, the interviewer will struggle to modify the prototype of the subclass will not affect the parent class? is really not affected, because the subclass of prototype is a pointer to the middle constructor generated instance, if really want to change, dog.prototype.__proto__ so to change.

object.create ()
function Animal() {}Animal.prototype.species = '动物';function Dog(name, color) {    this.name = name;    this.color = color;}Dog.prototype = Object.create(Animal.prototype,{    constructor: {        value: Dog    }})var hashiqi = new Dog('hashiqi','blackandwhite');console.log(hashiqi.species); //动物

3. Copy Inheritance

Shallow Copy
function Animal() {}Animal.prototype.species = '动物';function Dog(name, color) {    this.name = name;    this.color = color;}function extend(child, parent) {    var c = child.prototype;    var p = parent.prototype;    for(key in p) {        c[key] = p[key]    }}extend(Dog, Animal);var hashiqi = new Dog('hashiqi', 'blackandwhite');console.log(hashiqi.species) // 动物
Deep Copy
function deepCopy(parent, child) {    var child = child || {};    for(key in parent) {        if(typeof parent[key] === 'object') {            child[key] = parent[key].constructor === Array?[]:{};            deepCopy(parent[key],child[key])        } else {            child[key] = parent[key];        }    }    return child;}
ES6 Object-oriented

What is described above is the traditional way of JavaScript, which defines and generates new objects by constructing functions.
The ES6 provides a more similar approach to traditional languages, introducing the concept of class, which allows you to define classes through the Class keyword.

Grammar

The class of ES6 can be considered as another way of writing a constructor function.

var method = 'say';class Dog {    constructor (name,color) {        this.name = name;        this.color = color;    }    //注意,两个属性之间跟对象不同,不要加逗号,并且类的属性名可以使用变量或者表达式,如下    [method] () {        console.log('汪汪');    }}console.log(typeof Dog); // function 类的数据类型就是函数console.log(Dog === Dog.prototype.constructor); // true 类本身就是构造函数

Since it is a constructor, you use the new command directly on the class when used, exactly as the constructor uses.

var hashiqi = new Dog('hashiqi', 'blackandwhite');console.log(hashiqi.color); // blackandwhite//上面采用表达式声明的类的属性可以用一下两种方式调用hashiqi[method](); // 汪汪hashiqi.say(); // 汪汪

Attention:
1, first declare the definition of the class, and then create an instance, otherwise it will error
Class does not have a variable promotion, which is completely different from the ES5 constructor

new Dog('hashiqi','blackandwhite')class Dog {    constructor (name,color) {        this.name = name;        this.color = color;    }}//Uncaught ReferenceError: Dog is not defined//上面代码,Dog类使用在前,定义在后,因为ES6不会把类的声明提升到代码头部,所以报错Dog没有定义。

2. You must use the New keyword to create an instance object of the class
The constructor of the class, without using new, cannot be called and will error. This is a major difference from the normal constructor, which can be executed without new.

class Dog {    constructor (name,color) {        this.name = name;        this.color = color;    }}Dog(); // Uncaught TypeError: Class constructor Dog cannot be invoked without 'new'

3, the definition of "class" method, the front does not need to add the function of the keyword, directly put the definition of functions in the can be. Also, the method does not need a comma separation, plus will error.

Attribute Concepts

Constructor Constructor function

The constructor method, constructor, is a method that a class must have to return the instance object by default, and this method is called when an instance object of the class is created to initialize the instance object. If you do not write the constructor method, the execution will be accompanied by a default empty constructor method.

The constructor method is necessary and unique, and a class body cannot contain multiple constructor construction methods.

class Dog {    constructor (name,color) {        this.name = name;        this.color = color;    }    //定义了两个constructor,所以会报错    constructor () {            }}new Dog('hashiqi', 'blackandwhite')//Uncaught SyntaxError: A class may only have one constructor
Class-expression

As with functions, a class can be defined in the form of an expression.

const Hashiqi = class Dog {    constructor (name,color) {        this.name = name;        this.color = color;    }    getName () {        //此处的Dog就是Dog构造函数,在表达式形式中,只能在构造函数内部使用        console.log(Dog.name);    }}var hashiqi = new Hashiqi('hashiqi', 'blackandwhite'); // 真正的类名是Hashiqivar jinmao = new Dog('jinmao', 'yellow'); // 会报错,Dog没有定义

Usually our expression is written as follows, omitting the name after the class

const Hashiqi = class {    constructor (name,color) {        this.name = name;        this.color = color;    }}var hashiqi = new Hashiqi('hashiqi', 'blackandwhite');
Instance methods
and methods that are instantiated by a static method are called instance methods. A method that can be accessed directly using the class name, called a "static method"

Class is equivalent to the prototype of an instance, and all methods defined in the class are inherited by the instance. If you precede a method with the static keyword, it means that the method is not inherited by the instance, but instead is called directly through the class, which is called a "static method."

class Dog {    constructor (name,color) {        this.name = name;        this.color = color;    }    static say () {        console.log('汪汪');    }}Dog.say(); //汪汪

Static and instance methods differ: the definition of a static method needs to be identified by using the static keyword, which is not required by the instance method, and the static method is called through the class name, and the instance method is invoked through the instance object.

Inheritance of Classes

extends

Classes can be inherited through the extends keyword, which is much clearer and more convenient than ES5 by modifying the prototype chain to achieve inheritance.

class Dog extends Animal{}

Extends's successor goal
Extends keyword can be followed by multiple types of values, there are three special cases

1. Subclass Inherits Object class

class A extends Object {}console.log(A.__proto__ === Object) //trueconsole.log(A.prototype.__proto__ == Object.prototype) //true//这种情况下,A其实就是构造函数Object的复制,A的实例就是Object的实例。

2. There is no inheritance

class A {}console.log(A.__proto__ === Function.prototype) // trueconsole.log(A.prototype.__proto__ === Object.prototype) // true//这种情况下,A作为一个基类(即不存在任何继承),就是一个普通函数,所以直接继承Funciton.prototype。//但是,A调用后返回一个空对象(即Object实例),所以A.prototype.__proto__指向构造函数(Object)的prototype属性。

3. Subclass Inherits Null

class A extends null {}console.log(A.__proto__ === Function.prototype) //trueconsole.log(A.prototype) //只有一个constructor属性,没有__proto__属性这种情况与第二种情况非常像。A也是一个普通函数,所以直接继承Funciton.prototype。但是,A调用后返回的对象不继承任何方法,所以没有__proto__这属性
Super

The Uper keyword can be used either as a function or as an object.

1. When super is called as a function, it represents the constructor of the parent class. As a function, super () can only be used in the constructor of a subclass, and it can be used elsewhere to make an error.

2, super as an object, in the normal method, point to the parent class of the prototype object; In a static method, point to the parent class.

class Animal {    constructor (name) {        this.name = name;        this.species = '动物';    }    say (){        return this.species;    }}class Dog extends Animal{    constructor (name, color) {        // 只要是自己在子类中定义constructor,必须调用super方法,否则新建实例会报错        //super作为函数调用,只能用在子类的constructor中        super(name);        this.color = color;    }    getInfo () {        //普通方法中,super指向父类的原型对象        console.log(super.say()+': '+this.name +','+this.color);    }}var hashiqi = new Dog('hashiqi', 'blackandwhite');hashiqi.getInfo() //动物:hashiqi,balckandwhite

Attention:
1. Subclasses must call the Super method in the constructor method, or the new instance will have an error. This is because the subclass does not have its own this object, but instead inherits the parent class's this object and then processes it. If you do not call the Super method, the subclass will not get the This object.

2. In the normal method of a subclass, because super points to the prototype object of the parent class, the method or property defined on the parent class instance cannot be called by Super.

3, when using super, you must explicitly specify whether to use as a function, or as an object, or you will get an error.

Original address: 1190000012728341

Object-oriented JavaScript

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.