怎样建立对象以及jQuery中建立对象的体式格局

1. 运用对象字面量建立对象 key-value
var cat = {
    name: 'tom',
    info: this.name + ': 1212',
    getName: function() {
        return this.name;
    }
};

注重上例属性info中,运用了this.name,这里的this指向window对象,请只管防止在定义对象属性时运用表达式,而将有表达式的内容写入到函数中。

2.运用new建立对象
var dog = new Object();
dog.name = 'tim';
dog.getName = function() {
    return dog.name;
}
  • 可以运用delete删除对象的属性和要领
delete dog.name;

在window作用域中,不能运用delete删除var, function定义的属性和要领,可以删除没有运用var, function定义的属性和要领

3. 工场形式

在实际运用当中,字面量建立对象虽然很有效,然则它并不能满足我们的一切需求,我们愿望可以可以和其他背景言语一样建立一个类,然后声明类的实例就可以屡次运用,而不必每次运用的时刻都要从新建立它,因而,便有了工场形式的涌现。

function person(name) {
    var o = new Object();
    o.name = name;
    o.getName = function() {
        return this.name;
    }
    return o;
}
var person1 = person('rose');
var person2 = person('jake');

这类形式在函数的内部建立了一个空对象,然后一一增加属性和要领,末了返回,完成了对象得以复用的目标。然则存在2个很大的题目

  • 没法辨认对象的范例
console.log(person1 instanceof person); // false
  • 每一个对象挪用的同名要领着实并不同一个要领
console.log(person1.getName == person2.getName); // false

着实就相当于每次声明对象都被从新建立,只不过写法上简朴了一点罢了。

4. 自定义组织函数
var Person = function(name) {
    this.name = name;
    this.getName = function() {
        return this.name;
    }
}

var person1 = new Person('tom');
var person2 = new Person('tim');

运用var或许function声明函数都可以,只是我写例子的时刻想到什么就写了什么,这个区分在这里不是重点

和工场形式比拟,自定义组织函数没有在函数内部显现的建立和返回对象,而是运用this,固然,看上去简约了许多,那末它处理了工场形式的什么题目呢?

console.log(person1 instanceof Person);  // ture
console.log(person1.getName == person2.getName); //false

从上面代码可以看出,对象的种别可以判断了,person1就是Person的对象,但是2个同名要领任然不是同一个要领,而是从新建立,着实组织函数内部的完成,可以将上面的代码写成如许来明白

var Person = function(name) {
    var this = {};
    this.name = name;
    this.getName = function() {
        return this.name;
    }
    return this;
}

看上去和工场形式就有点像,只是this的声明和返回都是隐式的。下一步,我们将要引见症结教师,原型

原型

原型并没有那末神奇,由于在javascript中,它无处不在。为了相识原型,我们可以在chrome浏览器的console中,随便建立一个函数

function a(){}

然后继承输入

a.prototype

获得的效果以下

a {
    constructor: function a(),
    _proto_: Object
}

没错,获得的这个a,就是症结教师原型了。每一个函数都有一个prototype属性,他就像一个指针一样指向它的原型,而每一个原型,都有一个constructor属性,指向他的组织函数。
那末原型在建立对象中有什么用呢?
一个例子,精益求精,以下

 function Person(name) {
     this.name = name;
 }
 Person.prototype.getName = function() {
     return this.name;
 }

 var person1 = new Person('rose');
 var person2 = new Person('Jake');

在这里,我们将属性写在了组织函数里,将令人头疼的要领写在原型里,看看上面的题目获得处理没有

console.log(person1 instanceof Person); // true
console.log(person1.getName === person2.getName); // true

OK,题目圆满处理。

固然也可以将属性写入原型中,然则假如那样的话,属性就会犹如要领一样被公用了,因而一般来说,属性会写入组织函数当中,要领写入原型当中。固然,这视情况而定。

假如你想进一步相识原型,可以看下图。

《怎样建立对象以及jQuery中建立对象的体式格局》

当我们运用new Person时便会建立一个实例,比方这里的person1与person2,这里的实例中,会有一个_proto_属性指向原型。

  • 原型中的查找机制

当我们运用实例person1挪用要领person.getName()时,我们起首找的,是看看组织函数内里有无这个要领,假如组织函数中存在,就直接挪用组织函数的要领,假如组织函数不存在,才归去查找原型中是不是存在该要领

function Cat(name) {
    this.name = name;
    this.age = 12;
    this.getName = function() {
        return 'constructor';
    }
}
Cat.prototype.name = 'proto name';
Cat.prototype.getName = function() {
    return this.name;
}

var tim = new Cat('Tim');
console.log(tim.name);  // tim
console.log(tim.getName());  // constructor

可以看到上例中,当原型和组织函数中具有一样的要领和属性的时刻,组织函数中的被实行。
因而,这里便会有一个十分重要的观点须要明白,那就是this的指向题目。
在全部建立对象的历程当中,this究竟指向谁?

 function Person(name) {
     this.name = name;
    //  this.getName = function() {
    //      return 'constructor';
    //  }
 }
 Person.prototype.getName = function() {
     return this.name;
 }
 Person.prototype.showName = function() {
     return this.getName();
 }

var rose = new Person('rose');
console.log(rose.showName()); //rose

着实在new实行时,组织函数中的this与原型中的this都被强行指向了new建立的实例对象。

假如须要写在原型上的要领许多的话,还可以如许来写,让写法看上去越发简约

Person.prototype = {
    constructor: Person,
    getName: function(){},
    showName: function(){},
    ...
}

constructor:Person这一句必不可少,由于{}也是一个对象,当运用Person.prototype = {}时,相当于从新定义了prototype的指向,因而手动修改{}constructor属性,让他成为Person的原型。

5. jQuery中建立对象是怎样完成的?

着实经由过程上面体式格局,运用组织函数声明实例的专属变量和要领,运用原型声明公用的实例和要领,已经是建立对象的圆满处理方案了。但是唯一的不足在于,每次建立实例都要运用new来声明。如许难免太甚贫苦,假如jquery对象也如许建立,那末你就会看到一段代码中有无数个new,但是jQuery仅仅只是运用了$(‘xxxx’)便完成了实例的建立,这是怎样做到的呢?

照样根据通例,先贴代码。

 (function(window, undefined) {
     var Person = function(name) {
         return new Person.fn.init(name);
     }

     Person.prototype = Person.fn = {
         constructor: Person,

         init: function(name) {
             this.name = name;
             return this;
         },

         getName: function() {
             return this.name;
         }
     }
     Person.fn.init.prototype = Person.fn;
     window.Person = window.$ = Person;
 })(window);

 console.log($('tom').getName());

一步一步来剖析

  • 起首为了防止变量污染,运用了函数自实行的体式格局。这类体式格局让javascript代码具有了模块的特征,因而大多数js库都邑如许做
(function(){
    ...
})()

传入window参数,是为了让jquery对象在外window中可以被接见,因而有以下一句代码

window.Person = window.$ = Person;

如许我们就可以直接运用$来挪用Person组织函数

  • 症结题目在于,真正的组织函数并非Person,而是Person原型中的init要领。个中的复杂关系,我们借助下图来剖析相识,表达能力着实有限,也不知道怎样才表达的越发简约易懂。

《怎样建立对象以及jQuery中建立对象的体式格局》

当外部挪用$().getName()时,函数内部的实行递次以下

new Person.fn.init()
// 而init的原型,经由过程下面一句指向了Person的原型
Person.fn.init.prototype = Person.fn;
// 因而就可以挪用原型中的getName要领了

《怎样建立对象以及jQuery中建立对象的体式格局》

    原文作者:九死蚕传人bo
    原文地址: https://segmentfault.com/a/1190000003997237
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞