js建立对象要领与历程+ES6的class

js建立对象有许多要领,以下是罕见要领整顿。

ES5建立对象

工场形式

function person (name, age, sex) {
    var O = new Object();
    O.name = name;
    O.age = age;
    O.sex = sex;
    O.sayName =function(){
        console.log(this.name);
    }
    return O;
}
var per = person("per",10,"male"); //不需要用new,由于有return,就是个一般函数,很好明白
console.log(per instanceof person); //false

组织函数形式

function Person (name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.sayName =function(){
        console.log(this.name);
    }
}
var per =new Person("per",10,"male"); 
console.log(per instanceof Person); //true

剖析建立历程,

 var per =new Person("per",10,"male"); 

在这行代码实行时,四个步骤:
①涌现了一个空的对象
②this指向这个对象
③实行组织函数的代码
④把这个对象取个名字是per,per的指针就指向这个对象,因而能够经由过程per操纵这个对象

工场形式定义出的对象,instanceof辨认不出是”person类”。
组织函数形式,每次new一个对象,内里的函数都邑建立一次,就这个sayName函数,明显共有同一个就能够了。
处理这个题目,涌现了原型形式:

原型形式

function Person () {
    Person.prototype.name = "p1";
    Person.prototype.age = 10;
    Person.prototype.sex = "female";
    Person.prototype.sayName =function(){
        console.log(this.name);
    }
}

那末,这些代码干了什么呢?
①当你建立Person()函数后,就会有一个prototype属性随之而来
我们能够看看,这个prototype是什么,实行以下代码:

 console.log(Person.prototype);

《js建立对象要领与历程+ES6的class》

_proto_保留继续自Object的要领。内里只要一个constructor属性指向Person()函数本身。
②固然我们是要用这个函数的,实行以下代码:

var per1 =new Person();
var per2 =new Person();
console.log(Person.prototype);

《js建立对象要领与历程+ES6的class》

在建立现实对象时刻,就会运转组织函数中的代码,而且per1、per2两个对象,就会实行两次组织函数的代码,但并不会多建立一个Person的prototype属性,只是从新赋值内里的name、age、sex和sayName变量。
③per1和per2有各自的prototype属性,指向Person的prototype属性。能够简朴明白为per1、per2各自的”指针”指向同一个”对象”。

这个原型形式啊,就真的彷佛单例形式了,每一个建立的对象都在操纵同一个对象。

最优:动态原型形式

function Person (name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    if(typeof this.sayName != "function"){  
        Person.prototype.sayName = function(){
            console.log(this.name);
        }
        Person.prototype.sayAge = function(){
            console.log(this.age);
        }
    }
}
var per = new Person("wlq", 19, "man");

如许的代码,使得每一个对象的name、age、sex都是各自的(不共有),然后函数写在原型上,就又是同享的,很不错。另有个处所,if语句的推断,使得第二次建立对象时刻,不会从新给Person.prototype.sayName和Person.prototype.sayAge重赋值。

原型重写的题目

function Person (name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    if(typeof this.sayName != "function"){
        Person.prototype.sayName = function(){
            console.log(this.name);
        }
    }
}
function WPerson (name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    if(typeof this.sayName != "function"){
        WPerson.prototype = {   //这里进行了原型的重写
            constructor: WPerson,
            sayName: function(){
                console.log(this.name);
            }
        }
    }
}
var per1 = new Person("w", 19, "man");
var per2 = new WPerson("q", 18, "man");
var per3 = new WPerson("q", 18, "man");
per1.sayName();  //输出w
per2.sayName();  //报错,说没有sayName这个要领
per3.sayName();  //输出q
console.log(per2.name);  //输出q

缘由

重写原型的发作是在建立对象今后的,per2指向的WPerson的原型上面只要name、age、sex,再建立完per2后,才实行WPerson原型的重写,per3以至今后建立的WPerson范例对象就都邑有sayName函数了。

革新要领

要领一(经由过程先实行一次WPerson的原型重写):

function WPerson (name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;       
}
WPerson.prototype = {  //写在建立对象之前
    constructor:WPerson,
    sayName: function(){
        console.log(this.name);
    }
}
var per = new WPerson("q", 18, "man");
per.sayName();  //输出q

要领二(提前先实行一次new):

   function WPerson (name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;  
        if(typeof this.sayName != "function"){
            WPerson.prototype = {  
                constructor:WPerson,
                sayName: function(){
                    console.log(this.name);
                }
            };
            return new WPerson(name,age,sex);  //首次运转时,多挪用一次new
           }
    }     
    var per = new WPerson("q", 18, "man");
    per.sayName();  //输出q
   

ES6中的class

class Point{
  constructor(x, y) {    //相当于java中的组织函数,假如不写默以为空
    this.x = x;          //x,y定义在对象本身上面
    this.y = y;
  }
  add() {                //该要领定义在Point.prototype上
    console.log(this.x + this.y);
  }
}
var p = new Point(2, 3);
p.add();  //输出5

能够说,class用法就是ES5中动态原型形式。

    原文作者:你才到碗里去
    原文地址: https://segmentfault.com/a/1190000013610498
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞