3.建構函式

kyo4311發表於2015-07-07

我打算用建構函式來寫這個外掛,於是我寫的程式碼如下:

;
(function ($) {
    function Quantity(opt) {
        this.init(opt);
    }

    Quantity.prototype.init = function (opt) {
        console.log(opt);
    };

    $.fn.quantity = function (opt) {
        return new Quantity(opt);
    };
}(jQuery));

什麼是建構函式?

通過 new 關鍵字方式呼叫的函式都被認為是建構函式,看來這個new很神奇啊。那麼new是幹嘛用的呢?new是用來例項化物件的,總結他幹了四件事。

1.建立了一個例項,重點要理建立這個詞。

function foo(){
}
var a = foo();
var b = foo();
console.log(a === b); //true

function Foo() {
}
var c = new Foo(); //新建立一個例項
var d = new Foo(); //新建立一個例項
console.log(c === d); //false

建立就是多了一個,然後是建立了兩個例項,就像雙胞胎一樣,既使長的一模一樣,他們也是兩個不同的人。

2.在建構函式內部,this 指向新建立的例項物件。

function foo() {
    console.log(this); //window
}
foo();

function Foo() {
    console.log(this); //Foo {}
}
new foo();

普通方式呼叫函式,this指向了window;而通過new方式的this 在函式體內指向了自己。理解這一點很重要,因為寫建構函式的時候需要用大量的this。

3.prototype被指向到例項物件上的的 prototype。

function Foo() {
    this.hi = 'hi!';
}

Foo.prototype.hello = function () {
    console.log(this.hi);
};

new Foo().hello(); //'hi!'
Foo.hello(); //TypeError: undefined is not a function

只有例項化之後的物件才能訪問prototype上面的屬性。

4.被呼叫的函式預設隱式的會返回 this(即新建立的物件)。

function foo() {}
function Foo() {}

console.log(foo()); //undefined
console.log(new foo()); //foo {}

事實上每個function都返回值的,如果不指定他就是undefined。但是重點是建構函式執行之後則隱式的會返回 this這是很有用的。這樣子我們就可以訪問到函式體內部的變數或是函式了。:)

建構函式的命名?

建構函式約定的命名為首字母大寫。所以在javascript裡面,看到首字母大寫的函式,我們就知道,前面要加new來例項化他。比如:

var a = new String(1); //{0: "1", length: 1, encodeHTML: function, [[PrimitiveValue]]: "1"}
var b = new Number(1); //{[[PrimitiveValue]]: 1}
var c = new RegExp('[0-9]'); ///[0-9]/
var d = new Array(0, 1, 2); //[0, 1, 2]
var e = new Object(); //{}

建構函式的記憶體分配?

首先來看一段程式碼:

function Cat(name, color) {    
    this.name = name;    
    this.color = color;    
    this.type = "貓科動物";    
    this.eat = function () {
        alert("吃老鼠");
    };  
}

var cat1 = new Cat('kitty', 'pink');
var cat2 = new Cat('iori', 'black');

程式碼很簡單,例項了兩個Cat,因為例項就是建立,所以每建立一個例項就得分配一個記憶體空間,我們可以通過prototype來改造這段程式碼讓他變的更合理一些。

function Cat(name, color) {    
    this.name = name;    
    this.color = color;    
    this.type = "貓科動物";    
}

//eat這個函式,在記憶體空間裡面只分配一次
Cat.prototype.eat = function () {
    alert("吃老鼠");
};

var cat1 = new Cat('kitty', 'pink');
var cat2 = new Cat('iori', 'black');

//兩個例項的eat()方法在同一個記憶體地址
console.log(cat1.eat === cat2.eat); //true

相關文章