国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

yacheng / 873人閱讀

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

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

原型對象與原型鏈

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

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

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 函數中的 this 表示原始對象,而并非原型對象.
    
// 構造函數,所有創建的對象都會有y屬性
function Foo(y) {
    this.y = y;
}
    
// 創建共享屬性x
Foo.prototype.x = 10;
    
// 創建共享方法calculate
Foo.prototype.calculate = function(z) {
    return this.x + this.y + z;
}
    
// 使用foo模式創建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"]

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

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

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

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

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

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

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

+"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);

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

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

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

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

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

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

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

自執行函數

在JavaScript里,任何function在執行的時候都會創建一個執行上下文。

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

當你聲明一個函數的時候,通過在后面加個括弧就可以實現自執行:

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

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

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

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

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

那么想要運行自執行函數有很多種方法:

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

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

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

// 比如:
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 */ } () // 如果需要傳遞參數,只需要加上括弧()
自執行匿名函數的應用

自執行匿名函數應用最多的場景可能就是閉包了。

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

看一個例子:

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

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

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

換句話說,setTimeout函數的代碼,被放到了第二梯隊,第一梯隊是執行for循環,循環完畢之后,才會執行setTimeout里的function。

所以當for循環執行完畢之后,i的值已經是6了。

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

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

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

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

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

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

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

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

相關文章

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

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

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

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

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

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

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

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

    JerryWangSAP 評論0 收藏0

發表評論

0條評論

yacheng

|高級講師

TA的文章

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