成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS基礎之常用小技巧和知識總結(二)

yacheng / 875人閱讀

摘要:組合使用構造函數(shù)模式和原型。構造函數(shù)用于定義實例屬性,原型鏈用于定定方法和共享的屬性。為了避免矛盾和意外的結果總是指定基數(shù)參數(shù)。

本文主要記錄平時開發(fā)遇到的知識點和小技巧

原型對象與原型鏈

JavaScritp 引擎在訪問對象的屬性時,如果在對象本身中沒有找到,則會去原型鏈中查找,如果找到,直接返回值,如果整個鏈都遍歷且沒有找到屬性,則返回 undefined.原型鏈一般實現(xiàn)為一個鏈表,這樣就可以按照一定的順序來查找。

原型鏈是一個由對象組成的有限對象鏈,實現(xiàn)繼承和共享屬性。

var base = {
    name: "base",
    getInfo: function() {
        return this.name;
    },
    getMoreInfo: function() {
         return this.id + ":" + this.name;
    }
}
var ext1 = {
    id: 0,
    name: "ext1"
    __proto__: base
}
var ext2 = {
    id: 9,
    __proto__: base
}
var ext3 = {
    id: 10,
    __proto__: base
}
console.log(ext1.id); // 0
console.log(ext1.getInfo()); // ext1

console.log(ext2.id); // 9
console.log(ext2.getInfo()); // base

console.log(ext3.id); // 10
console.log(ext3.getMoreInfo()); // 10:base

//getMoreInfo與getInfo 函數(shù)中的 this 表示原始對象,而并非原型對象.
    
// 構造函數(shù),所有創(chuàng)建的對象都會有y屬性
function Foo(y) {
    this.y = y;
}
    
// 創(chuàng)建共享屬性x
Foo.prototype.x = 10;
    
// 創(chuàng)建共享方法calculate
Foo.prototype.calculate = function(z) {
    return this.x + this.y + z;
}
    
// 使用foo模式創(chuàng)建b、c
var b = new Foo(10); // 此時b.y為10
var c = new Foo(20); // 此時c.y為20
    
//b、c分別調用共享方法
console.log(b.calculate(10)); // 30
console.log(c.calculate(10)); // 40
// 注意一點,this這個值在一個繼承機制中,仍然是指向它原本屬于的對象,而不是從原型鏈上找到它時, 它所屬于的對象。
function Person() {};

Person.prototype = {
    constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    friends: ["Shelby", "Court"],
    sayName: function() {
        alert(this.name);
    }
};

var person1 = new Person();

var person2 = new Person();

person1.friends.push("Grey");
console.log(person1.friends); // ["Shelby", "Court", "Grey"]
console.log(person2.friends); // ["Shelby", "Court", "Grey"]
console.log(person1.friends === person2.friends); // true

原型對象的問題,公共屬性可能會被篡改。這也是為什么很少看到有人使用原型鏈的原因。
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Shelby", "Court"];
}

Person.prototype = {
    constructor: Person,
    sayName: function() {
        alert(this.name);
    }
}

var person1 = new Person();

var person2 = new Person();

person1.friends.push("Grey");

console.log(person1.friends); // ["Shelby", "Court", "Grey"]

console.log(person2.friends); // ["Shelby", "Court"]

//組合使用構造函數(shù)模式和原型。
//構造函數(shù)用于定義實例屬性,原型鏈用于定定方法和共享的屬性。
數(shù)值轉換

使用 parseInt()你可以從字符串中獲取數(shù)值,該方法接受另一個基數(shù)參數(shù),可以省略,但不推薦。

當字符串以0開頭的時候,就有可能會出問題。

例如,部分時間進入表單域,在ECMAScript 3中,開頭為”0′′ 的字符串被當做8進制處理了,但這已在ECMAScript 5中改變了。為了避免矛盾和意外的結果,總是指定基數(shù)參數(shù)。

var month = "06", year = "09";
month = parseInt(month, 10);
year = parseInt(year, 10);

此例中,如果你忽略了基數(shù)參數(shù),如parseInt(year), 返回的值將是 0。
因為“09”被當做8進制(好比執(zhí) 行 parseInt( year, 8 )), 而09在8進制中不是個有效數(shù)字。

替換方法是將字符串轉換成數(shù)字,包括:

+"08" //  8 

Number("08") // 8 顯式轉換
 
"08" - 0 // 8 隱式轉換
Module模式

1.模塊化,可重用
2.封裝了變量和function, 與全局的命名空間不接觸, 松耦合
3.只暴露可用public的方法,其它私有方法全部隱藏.

var Calculator = function (eq) { 
    //這里可以聲明私有成員
    var eqCtl = document.getElementById(eq);
    return {
        // 暴露公開的成員
        add: function (x, y) {
            var val = x + y;
            eqCtl.innerHTML = val; 
        }
    }; 
};

// 我們可以通過如下的方式來調用:
var calculator = new Calculator("eq"); 
calculator.add(2, 2);

當然,我們也可以使用匿名函數(shù)來完成它,并且引用全局對象。

(function ($, YAHOO) {
// 這里,我們的代碼就可以使用全局的jQuery對象了,YAHOO也是一樣
} (jQuery, YAHOO));

Module模式的一個限制就是所有的代碼都要寫在一個文件,但是在一些大型項目里,將一個功能分離成多 個文件是非常重要的,因為可以多人合作易于開發(fā)。

var blogModule = (function (my) { 
    my.AddPhoto = function () {
        //添加內部代碼 
    };
    return my;
} (blogModule));

上面的代碼盡管可以執(zhí)行,但是必須先聲明blogModule,然后再執(zhí)行上面的擴展代碼,也就是說步驟不 能亂,怎么解決這個問題呢?我們可以在傳入?yún)?shù)的時候進行一些改變:

var blogModule = (function (my) {
    // 添加一些功能
    return my;
} (blogModule || {}));

通過這樣的代碼,每個多帶帶分離的文件都保證這個結構,那么我們就可以實現(xiàn)任意順序的加載。

自執(zhí)行函數(shù)

在JavaScript里,任何function在執(zhí)行的時候都會創(chuàng)建一個執(zhí)行上下文。

因為為function聲明的變量和 function有可能只在該function內部,這個上下文,在調用function的時候,提供了一種簡單的方式來創(chuàng) 建自由變量 或 私有的子function。

當你聲明一個函數(shù)的時候,通過在后面加個括弧就可以實現(xiàn)自執(zhí)行:

// 因為想下面第一個聲明的function可以在后面加一個括弧()就可以自己執(zhí)行了,比如foo(),
// 因為foo僅僅是function() { /* code */ }這個表達式的一個引用

var foo = function(){ 
    /* code */ 
}
// ...是不是意味著后面加個括弧都可以自動執(zhí)行?

function(){ 
/* code */ 
}(); // SyntaxError: Unexpected token

// 但是如果你在括弧()里傳入一個表達式,將不會有異常拋出
// 但是foo函數(shù)依然不會執(zhí)行
function foo(){ 
/* code */ 
}( 1 );

// 因為它完全等價于下面這個代碼,一個function聲明后面,又聲明了一個毫無關系的表達式:
function foo(){ /* code */ }(1);

那么想要運行自執(zhí)行函數(shù)有很多種方法:

(function () { /* code */ } ()); // 推薦使用這個

(function () { /* code */ })(); // 但是這個也是可以用的

// 由于括弧()和 JS的 &&,異或,逗號等操作符是在函數(shù)表達式和函數(shù)聲明上消除歧義的
// 所以一旦解析器知道其中一個是表達式了,其它的也都默認為表達式.

// 比如:
var i = function () { return 10; }();

true && function () { /* code */ }();

0, function () { /* code */ }();

如果你不在意返回值,或者不怕難以閱讀, 甚至可以在function前面加一元操作符號:

!function () { /* code */ } (); 

~function () { /* code */ } (); 

-function () { /* code */ } (); 

+function () { /* code */ } ();

// 使用new關鍵字,也可以用
new function () { /* code */ }
new function () { /* code */ } () // 如果需要傳遞參數(shù),只需要加上括弧()
自執(zhí)行匿名函數(shù)的應用

自執(zhí)行匿名函數(shù)應用最多的場景可能就是閉包了。

閉包可以創(chuàng)建額外的scope,這可以被用來組合相關的或有依賴性的代碼。用這種方式可以最大限度地減少代碼干擾的危害。但是濫用閉包也會產生一系列的副作用,比如內存泄露。在實際開發(fā)中,我們應該合理的應用閉包。

看一個例子:

for (var i=1; i<=5; i++) { 
    setTimeout( function() {
        console.log(i);
    }, i * 1000 );
}

這是一個經典的閉包題,我們想要的結果其實是輸出1-5,可是卻發(fā)現(xiàn)輸出的是5個6.

那是因為javascript是單線程,執(zhí)行代碼是以輪詢的形式進行執(zhí)行。

換句話說,setTimeout函數(shù)的代碼,被放到了第二梯隊,第一梯隊是執(zhí)行for循環(huán),循環(huán)完畢之后,才會執(zhí)行setTimeout里的function。

所以當for循環(huán)執(zhí)行完畢之后,i的值已經是6了。

那么我們可以用匿名函數(shù)閉包來解決這個問題:

for (var i=1; i<=5; i++) { 
    (function(i) {
        setTimeout( function() {
            console.log(i);
        }, i*1000 );
    })(i)
}

在setTimeout的外層包裹一個自執(zhí)行匿名函數(shù),并傳入i,根據(jù)閉包的特性,此時每次循環(huán)時的i值都保存在對應的閉包中,而不在受到外層i的影響,setTimeout里的function中輸出的i值,訪問的是其對應閉包中的值。

這個題目是考閉包的,其實我們使用值的傳遞,一樣可以得到同樣的結果,只不過那樣的話,可能就不是考官想要的答案了。

for (var i=1; i<=5; i++) { 
    setTimeout( function(i) {
        console.log(i);
    }, i*1000 ,i);
}

我們知道,函數(shù)的參數(shù)如果是普通類型值,是按值傳遞的。因此可以取巧,直接傳值,來得到想要的答案。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/84748.html

相關文章

  • 前端資源系列(4)-前端學習資源分享&前端面試資源匯總

    摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業(yè)務工作時也會不定期更...

    princekin 評論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個最重要的技術點常用整理網頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實現(xiàn)的大排序算法一怪對象常用方法函數(shù)收集數(shù)組的操作面向對象和原型繼承中關鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個最重要的技術點 常用meta整理 網頁性能管理詳解 HTML5 ...

    jsbintask 評論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個最重要的技術點常用整理網頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實現(xiàn)的大排序算法一怪對象常用方法函數(shù)收集數(shù)組的操作面向對象和原型繼承中關鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個最重要的技術點 常用meta整理 網頁性能管理詳解 HTML5 ...

    muddyway 評論0 收藏0
  • Web前端開發(fā)學習推薦--菜鳥必看

    Web前端開發(fā)是創(chuàng)建Web頁面或app等前端界面呈現(xiàn)給用戶的過程。第一階段:前端基礎(HTML / CSS / JavaScript / jQuery)初識HTML+CSS【學習筆記】HTML基礎完結篇html基礎知識——標簽詳解html基礎知識——與用戶交互!(表單標簽)html基礎知識——css樣式①史上最全Html和CSS布局技巧面試題匯總 HTML+CSS篇CSS 最核心的幾個概念純HTM...

    JerryWangSAP 評論0 收藏0

發(fā)表評論

0條評論

yacheng

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<