摘要:實際上,可以將其理解為某種形式的繼承。如果上下文是,則使用全局對象代替。例如的第個參數是上下文,后續是實際傳入的參數序列中允許更換上下文是為了共享狀態,尤其是在事件回調中。
公開記錄學習JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應用開發》為主要學習資料。接上一篇類的學習,發現實在是看暈了,有些例子是能看懂在干嘛,但是不知道為什么這樣做,有的甚至看不懂,真是博大精深!
基于原型的類繼承JavaScript 是基于原型的編程語言,原型用來區別類和實例。原型是一個“模板”對象,它上面的屬性被用做初始化一個新對象。任何對象都可以作為另一個對象的原型對象,以此來共享屬性。實際上,可以將其理解為某種形式的繼承。
當讀取一個對象的屬性時,JavaScript 首先會在本地對象中查找這個屬性,如果沒有找到,JavaScript 開始在對象的原型中查找,若還未找到還會繼續查找原型的原型,直到查找到Object.prototype。如果找到這個屬性,則返回這個值,否則返回undefined。例如,給 Array.prototype 添加了屬性,那么所有的 JavaScript 數組都具有了這些屬性。
讓子類繼承父類的屬性的方法:
先定義一個構造函數,然后將父類的新實例賦值給構造函數的原型:
// 父,動物大類 var Animal = function(){}; Animal.prototype.breath = function(){ console.log("breath"); }; // 子,狗類 var Dog = function(){}; // Dog 繼承了Animal Dog.prototype = new Animal; Dog.prototype.wag = function(){ console.log("wag tail"); };
檢查繼承是否生效了:
var dog1 = new Dog; dog1.wag(); dog1.breath(); // 繼承的屬性給“類”庫添加繼承
通過傳入一個可選的父類來創建新類,這個可以作為創建類的基礎模板:
var Class = function(parent){ var klass = function(){ this.init.apply(this, arguments); }; // 改變klass 的原型 if (parent) { var subclass = function() { }; subclass.prototype = parent.prototype; klass.prototype = new subclass; }; klass.prototype.init = function(){}; // 定義別名 klass.fn = klass.prototype; klass.fn.parent = klass; klass._super = klass.__proto__; /* include/extend 相關的代碼…… */ return klass; };
如果將parent 傳入Class 構造函數,那么所有的子類則共享同一個原型。這種創建
臨時匿名函數的小技巧避免了在繼承類的時候創建實例,這里暗示了只有實例的屬性才會被繼承,而非類的屬性【我沒讀懂這句和上面代碼的關系,感覺已經暈了 = =】。設置對象的proto ;屬性并不是所有瀏覽器都支持,類似Super.js的類庫則通過屬性復制的方式來解決這
個問題,而非通過固有的動態繼承的方式來實現。
通過給Class 傳入父類來實現簡單的繼承:
var Animal = new Class; Animal.include({ breath: function(){ console.log("breath"); } }); var Cat = new Class(Animal); // 用法 var tommy = new Cat;函數調用
在JavaScript中,函數和其他東西一樣都是對象。和其他對象不同的是,函數可調用。函數內上下文,如this 的取值,取決調用它的位置和方法。
除了使用方括號可以調用函數之外,還有其他兩種方法可以調用函數:apply() 和 call()。兩者的區別在于傳入函數的參數的形式。
apply() 函數有兩個參數:第1個參數是上下文,第2個參數是參數組成的數組。如果上下文是null,則使用全局對象代替。例如:
function.apply(this, [1, 2, 3])
call()的第1個參數是上下文,后續是實際傳入的參數序列:
function.call(this, 1, 2, 3);
JavaScript 中允許更換上下文是為了共享狀態,尤其是在事件回調中。jQuery 在其API 的實現中就利用了apply() 和call() 來更改上下文,比如在事件處理程序中或者使用each() 來做迭代時。
$(".clicky").click(function(){ // ‘this’指向當前節點 $(this).hide(); }); $("p").each(function(){ // ‘this’指向本次迭代 $(this).remove(); });
為了訪問原始上下文,可以將this 的值存入一個局部變量中,這是一種常見的模式,比如:
var clicky = { wasClicked: function(){ /* ... */ }, addListeners: function(){ var self = this; $(".clicky").click(function(){ self.wasClicked() }); } }; clicky.addListeners();
可以用apply來將這段代碼變得更干凈一些,通過將回調包裝在另外一個匿名函數中,來保持原始的上下文:
var proxy = function(func, thisObject){ return(function(){ return func.apply(thisObject, arguments); }); }; var clicky = { wasClicked: function(){ /* ... */ }, addListeners: function(){ var self = this; $(".clicky").click(proxy(this.wasClicked, this)); } };
上面的例子中在點擊事件的回調中指定了要使用的上下文;jQuery中調用這個函數所用的上下文就可以忽略了。實際上jQuery也包含了實現了這個功能的API——jQuery.proxy() :
$(".clicky").click($.proxy(function(){ /* ... */ }, this));
使用apply()和call()還有其他很有用的原因,比如“委托”。可以將一個調用委托給另一個調用,甚至可以修改傳入的參數:
var App { log: function(){ if (typeof console == "undefined") return; // 將參數轉換為合適的數組 var args = jQuery.makeArray(arguments); // 插入一個新的參數 args.unshift("(App)"); // 委托給console console.log.apply(console, args); } };
這個例子中首先構建了一個參數數組,然后將參數添加進去,最后將這個調用委托給了console.log()。arguments變量是解釋器內置的當前調用的作用域內用來保存參數的數組。但它并不是真正的數組,比如它是不可變的,因此需要通過jQuery.makeArray()將其轉換為可用的數組。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91465.html
摘要:任何函數都可以用做構造函數,構造函數必須使用運算符作為前綴來創建新的實例。當使用關鍵字來調用構造函數時,執行上下文從全局對象變成一個空的上下文,這個上下文代表了新生成的實例。默認情況下,如果構造函數中沒有返回任何內容,就會返回當前的上下文。 公開記錄學習JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應用開發》為主要學習資料。 JavaScr...
摘要:基于函數進行調用的,用來確保函數是在指定的值所在的上下文中調用的。添加私有函數目前上面為類庫添加的屬性都是公開的,可以被隨時修改。以基于的富應用開發為主要學習資料。 控制類庫的作用域 在類和實例中都添加proxy函數,可以在事件處理程序之外處理函數的時候保持類的作用域。下面是不用proxy的辦法: var Class = function(parent){ var klas...
摘要:以基于的富應用開發為主要學習資料。下面用實現一個例子使用匿名函數來封裝一個作用域在頁面加載時綁定事件監聽上面的代碼創建了控制器,這個控制器是放在變量下的命名空間。然后用了一個匿名函數封裝了一個作用域,以避免對全局作用域造成污染。 公開記錄學習JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應用開發》為主要學習資料。 什么是MVC MVC 是一種設...
閱讀 3292·2021-11-23 09:51
閱讀 945·2021-09-03 10:30
閱讀 3218·2021-08-31 09:40
閱讀 3281·2019-08-30 14:22
閱讀 906·2019-08-30 14:09
閱讀 2904·2019-08-30 13:21
閱讀 3240·2019-08-28 18:03
閱讀 2863·2019-08-26 13:44