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

資訊專欄INFORMATION COLUMN

〔總結(jié)〕容易遺忘的JS知識(shí)點(diǎn)整理

explorer_ddf / 1333人閱讀

摘要:命名函數(shù)的賦值表達(dá)式另外一個(gè)特殊的情況是將命名函數(shù)賦值給一個(gè)變量。這是由于的命名處理所致,函數(shù)名在函數(shù)內(nèi)總是可見的。當(dāng)需要向回調(diào)函數(shù)傳遞參數(shù)時(shí),可以創(chuàng)建一個(gè)匿名函數(shù),在函數(shù)內(nèi)執(zhí)行真實(shí)的回調(diào)函數(shù)。

1.hasOwnProperty相關(guān)

為了判斷一個(gè)對(duì)象是否包含自定義屬性而不是原型鏈上的屬性,我們需要使用繼承自 Object.prototypehasOwnProperty方法。
hasOwnPropertyJavaScript 中唯一一個(gè)處理屬性但是不查找原型鏈的函數(shù)。

</>復(fù)制代碼

  1. // 修改Object.prototype
  2. Object.prototype.bar = 1;
  3. var foo = {goo: undefined};
  4. foo.bar; // 1
  5. "bar" in foo; // true
  6. foo.hasOwnProperty("bar"); // false
  7. foo.hasOwnProperty("goo"); // true

</>復(fù)制代碼

  1. 注意: 通過判斷一個(gè)屬性是否 undefined 是不夠的。 因?yàn)橐粋€(gè)屬性可能確實(shí)存在,只不過它的值被設(shè)置為 undefined
hasOwnProperty 作為屬性

JavaScript 不會(huì)保護(hù) hasOwnProperty 被非法占用,因此如果一個(gè)對(duì)象碰巧存在這個(gè)屬性, 就需要使用外部的 hasOwnProperty 函數(shù)來獲取正確的結(jié)果。

</>復(fù)制代碼

  1. var foo = {
  2. hasOwnProperty: function() {
  3. return false;
  4. },
  5. bar: "Here be dragons"
  6. };
  7. foo.hasOwnProperty("bar"); // 總是返回 false
  8. // 使用其它對(duì)象的 hasOwnProperty,并將其上下文設(shè)置為foo
  9. ({}).hasOwnProperty.call(foo, "bar"); // true

當(dāng)檢查對(duì)象上某個(gè)屬性是否存在時(shí),hasOwnProperty 是唯一可用的方法。 同時(shí)在使用 for in loop遍歷對(duì)象時(shí),推薦總是使用 hasOwnProperty 方法, 這將會(huì)避免原型對(duì)象擴(kuò)展帶來的干擾。

for in 循環(huán)

in 操作符一樣,for in 循環(huán)同樣在查找對(duì)象屬性時(shí)遍歷原型鏈上的所有屬性。

</>復(fù)制代碼

  1. // 修改 Object.prototype
  2. Object.prototype.bar = 1;
  3. var foo = {moo: 2};
  4. for(var i in foo) {
  5. console.log(i); // 輸出兩個(gè)屬性:bar 和 moo
  6. }

</>復(fù)制代碼

  1. 注意: 由于 for in 總是要遍歷整個(gè)原型鏈,因此如果一個(gè)對(duì)象的繼承層次太深的話會(huì)影響性能。

由于不可能改變 for in 自身的行為,因此有必要過濾出那些不希望出現(xiàn)在循環(huán)體中的屬性, 這可以通過 Object.prototype 原型上的 hasOwnProperty 函數(shù)來完成。

使用 hasOwnProperty 過濾

</>復(fù)制代碼

  1. // foo 變量是上例中的
  2. for(var i in foo) {
  3. if (foo.hasOwnProperty(i)) {
  4. console.log(i);
  5. }
  6. }

</>復(fù)制代碼

  1. 推薦總是使用 hasOwnProperty。不要對(duì)代碼運(yùn)行的環(huán)境做任何假設(shè),不要假設(shè)原生對(duì)象是否已經(jīng)被擴(kuò)展了。
2.命名函數(shù)的賦值表達(dá)式

另外一個(gè)特殊的情況是將命名函數(shù)賦值給一個(gè)變量。

</>復(fù)制代碼

  1. var foo = function bar() {
  2. bar(); // 正常運(yùn)行
  3. }
  4. bar(); // 出錯(cuò):ReferenceError

bar 函數(shù)聲明外是不可見的,這是因?yàn)槲覀円呀?jīng)把函數(shù)賦值給了 foo; 然而在 bar 內(nèi)部依然可見。這是由于 JavaScript 的命名處理所致, 函數(shù)名在函數(shù)內(nèi)總是可見的。

</>復(fù)制代碼

  1. 注意:在IE8及IE8以下版本瀏覽器bar在外部也是可見的,是因?yàn)闉g覽器對(duì)命名函數(shù)賦值表達(dá)式進(jìn)行了錯(cuò)誤的解析, 解析成兩個(gè)函數(shù) foo 和 bar
3.方法的賦值表達(dá)式

另一個(gè)看起來奇怪的地方是函數(shù)別名,也就是將一個(gè)方法賦值給一個(gè)變量。

</>復(fù)制代碼

  1. var test = someObject.methodTest;
  2. test();

上例中,test 就像一個(gè)普通的函數(shù)被調(diào)用;因此,函數(shù)內(nèi)的 this 將不再被指向到 someObject 對(duì)象。而是指向了window。

4.循環(huán)中的閉包

一個(gè)常見的錯(cuò)誤出現(xiàn)在循環(huán)中使用閉包,假設(shè)我們需要在每次循環(huán)中調(diào)用循環(huán)序號(hào)

</>復(fù)制代碼

  1. for(var i = 0; i < 10; i++) {
  2. setTimeout(function() {
  3. console.log(i);
  4. }, 1000);
  5. }

上面的代碼不會(huì)輸出數(shù)字 0 9,而是會(huì)輸出數(shù)字10 十次。

當(dāng) console.log 被調(diào)用的時(shí)候,匿名函數(shù)保持對(duì)外部變量i的引用,此時(shí) for循環(huán)已經(jīng)結(jié)束,i的值被修改成了10.

為了得到想要的結(jié)果,需要在每次循環(huán)中創(chuàng)建變量 i的拷貝。

為了避免引用錯(cuò)誤,為了正確的獲得循環(huán)序號(hào),最好使用 匿名包裝器(注:其實(shí)就是我們通常說的自執(zhí)行匿名函數(shù))。

</>復(fù)制代碼

  1. for(var i = 0; i < 10; i++) {
  2. (function(e) {
  3. setTimeout(function() {
  4. console.log(e);
  5. }, 1000);
  6. })(i);
  7. }

外部的匿名函數(shù)會(huì)立即執(zhí)行,并把 i 作為它的參數(shù),此時(shí)函數(shù)內(nèi) e 變量就擁有了 i 的一個(gè)拷貝。

當(dāng)傳遞給 setTimeout 的匿名函數(shù)執(zhí)行時(shí),它就擁有了對(duì) e 的引用,而這個(gè)值是不會(huì)被循環(huán)改變的。

有另一個(gè)方法完成同樣的工作,那就是從匿名包裝器中返回一個(gè)函數(shù)。這和上面的代碼效果一樣。

</>復(fù)制代碼

  1. for(var i = 0; i < 10; i++) {
  2. setTimeout((function(e) {
  3. return function() {
  4. console.log(e);
  5. }
  6. })(i), 1000)
  7. }
5.對(duì)象使用和屬性

JavaScript 中所有變量都可以當(dāng)作對(duì)象使用,除了兩個(gè)例外 nullundefined。

</>復(fù)制代碼

  1. false.toString(); // "false"
  2. [1, 2, 3].toString(); // "1,2,3"
  3. function Foo(){}
  4. Foo.bar = 1;
  5. Foo.bar; // 1

一個(gè)常見的誤解是數(shù)字的字面值(literal)不能當(dāng)作對(duì)象使用。這是因?yàn)?JavaScript 解析器的一個(gè)錯(cuò)誤, 它試圖將點(diǎn)操作符解析為浮點(diǎn)數(shù)字面值的一部分。

</>復(fù)制代碼

  1. 2.toString(); // 出錯(cuò):SyntaxError

有很多變通方法可以讓數(shù)字的字面值看起來像對(duì)象。

</>復(fù)制代碼

  1. 2..toString(); // 第二個(gè)點(diǎn)號(hào)可以正常解析
  2. 2 .toString(); // 注意點(diǎn)號(hào)前面的空格
  3. (2).toString(); // 2先被計(jì)算

刪除屬性的唯一方法是使用 delete 操作符;設(shè)置屬性為 undefined 或者 null 并不能真正的刪除屬性, 而僅僅是移除了屬性和值的關(guān)聯(lián)。

</>復(fù)制代碼

  1. var obj = {
  2. bar: 1,
  3. foo: 2,
  4. baz: 3
  5. };
  6. obj.bar = undefined;
  7. obj.foo = null;
  8. delete obj.baz;
  9. for(var i in obj) {
  10. if (obj.hasOwnProperty(i)) {
  11. console.log(i, "" + obj[i]);
  12. }
  13. }

上面的輸出結(jié)果有 bar undefined foo null - 只有 baz 被真正的刪除了,所以從輸出結(jié)果中消失。

6.arguments 對(duì)象

JavaScript 中每個(gè)函數(shù)內(nèi)都能訪問一個(gè)特別變量 arguments。這個(gè)變量維護(hù)著所有傳遞到這個(gè)函數(shù)中的參數(shù)列表。

arguments 變量不是一個(gè)數(shù)組(Array)。 盡管在語(yǔ)法上它有數(shù)組相關(guān)的屬性 length,但它不從 Array.prototype 繼承,實(shí)際上它是一個(gè)對(duì)象(Object)。

因此,無法對(duì) arguments 變量使用標(biāo)準(zhǔn)的數(shù)組方法,比如 push, pop 或者 slice。 雖然使用 for 循環(huán)遍歷也是可以的,但是為了更好的使用數(shù)組方法,最好把它轉(zhuǎn)化為一個(gè)真正的數(shù)組。

轉(zhuǎn)化為數(shù)組

下面的代碼將會(huì)創(chuàng)建一個(gè)新的數(shù)組,包含所有 arguments 對(duì)象中的元素。

</>復(fù)制代碼

  1. Array.prototype.slice.call(arguments);

arguments 對(duì)象為其內(nèi)部屬性以及函數(shù)形式參數(shù)創(chuàng)建 getter setter 方法。

因此,改變形參的值會(huì)影響到 arguments 對(duì)象的值,反之亦然。

</>復(fù)制代碼

  1. function foo(a, b, c) {
  2. arguments[0] = 2;
  3. a; // 2
  4. b = 4;
  5. arguments[1]; // 4
  6. var d = c;
  7. d = 9;
  8. c; // 3
  9. }
  10. foo(1, 2, 3);

如下一個(gè)例子:

</>復(fù)制代碼

  1. function sidEffecting(ary) {
  2. ary[0] = ary[2];
  3. }
  4. function bar(a,b,c) {
  5. c = 10
  6. sidEffecting(arguments);
  7. return a + b + c;
  8. }
  9. bar(1,1,1)

這里所有的更改都將生效,a和c的值都為10,a+b+c的值將為21。

7.類型相關(guān) 測(cè)試為定義變量

</>復(fù)制代碼

  1. typeof foo !== "undefined"

上面代碼會(huì)檢測(cè) foo 是否已經(jīng)定義;如果沒有定義而直接使用會(huì)導(dǎo)致 ReferenceError 的異常。 這是 typeof 唯一有用的地方。當(dāng)然也能判斷出來基本類型。

Object.prototype.toString檢測(cè)一個(gè)對(duì)象的類型

為了檢測(cè)一個(gè)對(duì)象的類型,強(qiáng)烈推薦使用 Object.prototype.toString 方法

如下例子:

</>復(fù)制代碼

  1. Object.prototype.toString.call([]) // "[object Array]"
  2. Object.prototype.toString.call({}) // "[object Object]"
  3. Object.prototype.toString.call(2) // "[object Number]"
類型轉(zhuǎn)換

內(nèi)置類型(比如 NumberString)的構(gòu)造函數(shù)在被調(diào)用時(shí),使用或者不使用 new 的結(jié)果完全不同。

</>復(fù)制代碼

  1. new Number(10) === 10; // False, 對(duì)象與數(shù)字的比較
  2. Number(10) === 10; // True, 數(shù)字與數(shù)字的比較
  3. new Number(10) + 0 === 10; // True, 由于隱式的類型轉(zhuǎn)換

轉(zhuǎn)換為字符串

</>復(fù)制代碼

  1. "" + 10 === "10"; // true

將一個(gè)值加上空字符串可以輕松轉(zhuǎn)換為字符串類型。

轉(zhuǎn)換為數(shù)字

</>復(fù)制代碼

  1. +"10" === 10; // true

使用一元的加號(hào)操作符,可以把字符串轉(zhuǎn)換為數(shù)字。

轉(zhuǎn)換為布爾型

通過使用 操作符兩次,可以把一個(gè)值轉(zhuǎn)換為布爾型。

</>復(fù)制代碼

  1. !!"foo"; // true
  2. !!""; // false
  3. !!"0"; // true
  4. !!"1"; // true
  5. !!"-1" // true
  6. !!{}; // true
  7. !!true; // true
8.為什么不要使用 eval

eval 函數(shù)會(huì)在當(dāng)前作用域中執(zhí)行一段 JavaScript 代碼字符串。

</>復(fù)制代碼

  1. var foo = 1;
  2. function test() {
  3. var foo = 2;
  4. eval("foo = 3");
  5. return foo;
  6. }
  7. test(); // 3
  8. foo; // 1

但是 eval 只在被直接調(diào)用并且調(diào)用函數(shù)就是 eval 本身時(shí),才在當(dāng)前作用域中執(zhí)行。

</>復(fù)制代碼

  1. var foo = 1;
  2. function test() {
  3. var foo = 2;
  4. var bar = eval;
  5. bar("foo = 3");
  6. return foo;
  7. }
  8. test(); // 2
  9. foo; // 3

上面的代碼等價(jià)于在全局作用域中調(diào)用 eval,和下面兩種寫法效果一樣:

</>復(fù)制代碼

  1. // 寫法一:直接調(diào)用全局作用域下的 foo 變量
  2. var foo = 1;
  3. function test() {
  4. var foo = 2;
  5. window.foo = 3;
  6. return foo;
  7. }
  8. test(); // 2
  9. foo; // 3
  10. // 寫法二:使用 call 函數(shù)修改 eval 執(zhí)行的上下文為全局作用域
  11. var foo = 1;
  12. function test() {
  13. var foo = 2;
  14. eval.call(window, "foo = 3");
  15. return foo;
  16. }
  17. test(); // 2
  18. foo; // 3

在任何情況下我們都應(yīng)該避免使用 eval 函數(shù)。99.9% 使用 eval 的場(chǎng)景都有不使用 eval 的解決方案。

eval 也存在安全問題,因?yàn)樗鼤?huì)執(zhí)行任意傳給它的代碼, 在代碼字符串未知或者是來自一個(gè)不信任的源時(shí),絕對(duì)不要使用 eval 函數(shù)。

9.定時(shí)器 手工清空定時(shí)器

</>復(fù)制代碼

  1. var id = setTimeout(foo, 1000);
  2. clearTimeout(id);
清除所有定時(shí)器

由于沒有內(nèi)置的清除所有定時(shí)器的方法,可以采用一種暴力的方式來達(dá)到這一目的。

</>復(fù)制代碼

  1. // 清空"所有"的定時(shí)器
  2. for(var i = 1; i < 1000; i++) {
  3. clearTimeout(i);
  4. }

可能還有些定時(shí)器不會(huì)在上面代碼中被清除(注:如果定時(shí)器調(diào)用時(shí)返回的 ID 值大于 1000), 因此我們可以事先保存所有的定時(shí)器 ID,然后一把清除。

建議不要在調(diào)用定時(shí)器函數(shù)時(shí),為了向回調(diào)函數(shù)傳遞參數(shù)而使用字符串的形式。

</>復(fù)制代碼

  1. function foo(a, b, c) {}
  2. // 不要這樣做
  3. setTimeout("foo(1,2, 3)", 1000)
  4. // 可以使用匿名函數(shù)完成相同功能
  5. setTimeout(function() {
  6. foo(1, 2, 3);
  7. }, 1000)

</>復(fù)制代碼

  1. 絕對(duì)不要使用字符串作為 setTimeout 或者 setInterval 的第一個(gè)參數(shù), 這么寫的代碼明顯質(zhì)量很差。當(dāng)需要向回調(diào)函數(shù)傳遞參數(shù)時(shí),可以創(chuàng)建一個(gè)匿名函數(shù),在函數(shù)內(nèi)執(zhí)行真實(shí)的回調(diào)函數(shù)。

    另外,應(yīng)該避免使用 setInterval,因?yàn)樗亩〞r(shí)執(zhí)行不會(huì)被 JavaScript 阻塞。

后續(xù)逐漸添加

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/92157.html

相關(guān)文章

  • 重學(xué)前端學(xué)習(xí)筆記(一)--前端發(fā)展史以及學(xué)習(xí)痛點(diǎn)

    摘要:筆記說明重學(xué)前端是程劭非前手機(jī)淘寶前端負(fù)責(zé)人在極客時(shí)間開的一個(gè)專欄,每天分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些要點(diǎn)筆記以及感悟,完整的可以加入的專欄學(xué)習(xí)原文有的語(yǔ)音,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱。 筆記說明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些要點(diǎn)筆記以及感悟,完整的可以...

    hlcfan 評(píng)論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(一)--前端發(fā)展史以及學(xué)習(xí)痛點(diǎn)

    摘要:筆記說明重學(xué)前端是程劭非前手機(jī)淘寶前端負(fù)責(zé)人在極客時(shí)間開的一個(gè)專欄,每天分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些要點(diǎn)筆記以及感悟,完整的可以加入的專欄學(xué)習(xí)原文有的語(yǔ)音,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱。 筆記說明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些要點(diǎn)筆記以及感悟,完整的可以...

    wayneli 評(píng)論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(一)--前端發(fā)展史以及學(xué)習(xí)痛點(diǎn)

    摘要:筆記說明重學(xué)前端是程劭非前手機(jī)淘寶前端負(fù)責(zé)人在極客時(shí)間開的一個(gè)專欄,每天分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些要點(diǎn)筆記以及感悟,完整的可以加入的專欄學(xué)習(xí)原文有的語(yǔ)音,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱。 筆記說明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些要點(diǎn)筆記以及感悟,完整的可以...

    davidac 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<