Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产一进一出视频网站,国产综合91,婷婷99精品国产97久久综合

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript開發中this給程序員挖的坑,你

          JavaScript開發中this給程序員挖的坑,你遇到過嗎?

          于程序員來說,this這個關鍵字應該是再熟悉不過了,在C++、C#以及Java中,它的身影隨處可見,this也可以說是編程語言JavaScript的精髓,但是一定也有不少JavaScript開發者都遇到過this的陷阱。

          在C++、C#、Java中,this擁有十分明確的含義,就是單純指向當前的對象實例,但是,在動態編程語言JavaScript中,相同的this寫法,卻有不同的含義。

          JavaScript中的this代表函數運行時自動生成的一個內部對象,只能在函數內部使用。并且,你不能在創建統計this的時候就確定它,而應該在函數執行時進行確定,所以,一不留神,你就會掉進意想不到的坑!

          0、誰調用了就誰來負責

          我們先來看看代碼:

          var name='a';

          var obj={

          name: 'b',

          getName: function() {

          console.log(this.name);

          }

          };

          obj.getName(); // b

          var getName=obj.getName;

          getName(); // a

          var obj2=(function() {

          return function() {

          console.log(this.name);

          }

          })();

          obj2(); // a

          首先,obj.getName()打印出來b,因為,obj調用了getName(),所以其this指向obj,this.name就是b。

          其次,getName()打印出a的原因:理由是此時的obj并不調用getName(),而是全局變量window,因此,結果是a

          最后,obj2中,因為采用了立即執行函數,它返回一個函數,而當我們調用時,調用它的也是全局變量window,所以打印結果也是a。

          需要注意的是,匿名函數內的this是指向window的,更準確的說是指向調用者。

          1、必須了解new的過程

          function Test() {

          console.log(this.name);

          }

          Test(); // a

          var test=new Test(); // undefined

          function Test2() {

          this.name='c';

          }

          var test2=new Test2();

          console.log(test2.name); // c

          為什么這個例子最終打印出來的是c呢?這里new的過程不可忽略,new Test2() 其實執行了三步動作:

          首先,創建一個空對象obj(var obj={};),然后,將這個空對象的[[Prototype]](__proto__)成員指向了Test2函數對象prototype成員對象最后,將Test2函數對象的this指針替換成obj:

          obj.__proto__=Test2.prototype;

          Test2.call(obj);

          當沒有顯式返回值或者返回為基本類型、null時,默認將 this 返回(參考2)

          因此,在這個例子中,當你使用new的時候,函數內部的this指向已經改變了,不再指向window。

          主要應該搞清楚new的過程,然后就知道打印出c的原因了。

          2、奇怪的return

          看過上面的例子后,你是否覺得已經掌握了new的函數內的this指向?千萬別掉以輕心,在JavaScript中,多的是例外,如:

          function Test3() {

          this.name='d';

          return {};

          }

          var test3=new Test3();

          console.log(test3.name); // undefined

          function Test4() {

          this.name='d';

          return 1;

          }

          var test4=new Test4();

          console.log(test4.name); // d

          可以再試試return 'd' | null | undefined中的一個或更多類型。

          結論:如果return的是一個對象(null除外),那么this指向的這個對象,否則this依舊指向實例對象。

          當下 Web 編程大行其道時,JavaScript無疑是使用最為廣泛的前端語言。JavaScript為我們提供了極佳的體驗,同時,我們在使用JavaScript時,又經常會因為JavaScript的一些奇怪的特性所坑。當然我們可能用一些簡單的方法即可避免這些問題。通過這些簡單的做法,你可以使JavaScript成為一門更好的語言,也讓你自己成為一個更好的程序員。

          ==、!=操作符

          JavaScript有兩組相等運算符:===和!==,以及它們邪惡的李生兄弟==和!=。===和!==這一組運算符會按照你期望的方式工作。如果兩個運算數類型一致且擁有相同的值,那么===返回true, !==返回false。而它們邪惡的孿生兄弟只有在兩個運算數類型一致時才會做出正確的判斷,如果兩個運算數是不同的類型,它們試圖去強制轉換值的類型。轉換的規則復雜且難以記憶。這里有一些有趣的例子:

          • ''=='0' //false

          • 0=='' //true

          • 0=='0' //true

          • false=='false' //false

          • false=='0' //true

          • false==undefined //false

          • false==null //false

          • null==undefined //true

          • ' \t\r\n'==0 //true

          ==運算符對傳遞性的缺乏值得我們警惕。我的建議是永遠不要使用那對邪惡的孿生兄弟。相反,請始終使用===和 !==。如果以上所有的比較使用===運算符,結果都是 false。

          with 語句

          JavaScript提供了一個with語句,本意是想用它來快捷地訪問對象的屬性。不幸的是,它的結果可能有時不可預料,所以應該避免使用它。下面的語句:

          with (obj) { a * b;}

          和下面的代碼做的是同樣的事情:

          1. if (obj.a===undefined) {

          2. a * obj.b===undefined ? b : obj.b;

          3. } else {

          4. obj.a=obj.b===undefined ? b : obj.b;

          5. }

          所以,它等于這些語句中的某一條:

          1. a=b

          2. a=obj.b;

          3. obj .a=b;

          4. obj.a=obj.b;

          通過閱讀程序代碼,你不可能辨別出你會得到的是這些語句中的哪一條。它可能隨著程序運行到下一步時發生變化。它甚至可能在程序運行過程中就發生了變化。如果你不能通過閱讀程序而了解它將會做什么,你就無法確信它會正確地做你想要做的事情。

          With語句在這門語言里存在,本身就嚴重影響了 JavaScript處理器的速度,因為它阻斷了變量名的詞法作用域綁定。它的本意是好的,但如果沒有它,JavaScript語言會更好一點。

          eval 語句

          eval函數傳遞一個字符串給JavaScript編譯器,并且執行其結果。它是一個被濫用得最多的JavaScript特性。那些對JavaScript語言一知半解的人們最常用到它。例如,如果你知道點表示法,但不知道下標表示法,就可能會這么寫:

          eval ("myValue=myObject." + myKey + ";")

          而不是這么寫:

          myvalue=myObject[myKey];

          使用eval形式的代碼更加難以閱讀。這種形式使得性能顯著降低,因為它需要運行編譯器,但也許只是為了執行一個微不足道的賦值語句。它也會讓JSLint 失效,讓此工具檢測問題的能力大打折扣。eval函數還減弱了你的應用程序的安全性,因為它給被求值的文本授予了太多的權力。而且就像with語句執行的方式一樣,它降低了語言的性能。Function構造器是eval的另一種形式,同樣也應該避免使用它。瀏覽器提供的setTimeout和setlnterval函數,它們能接受字符串參數或函數參數。當傳遞的是字符串參數時,setTimeout和setlnterval會像eval那樣去處理。同樣也應該避免使用字符串參數形式。

          位運算符

          JavaScript有著與Java相同的一套位運算符:

          1. & and按位與

          2. | or按位或

          3. ^ xor按位異或

          4. ~ not按位非

          5. >> 帶符號的右位移

          6. >>> 無符號的(用0補足的) 右位移

          7. << 左位移

          在Java里,位運算符處理的是整數。JavaScript沒有整數類型,它只有雙精度的浮點數。因此,位操作符把它們的數字運算數先轉換成整數,接著執行運算,然后再轉換回去。在大多數語言中,這些位運算符接近于硬件處理,所以非???。但JavaScript的執行環境一般接觸不到硬件,所以非常慢。JavaScript很少被用來執行位操作。還有,在JavaScript程序中,& 非常容易被誤寫為 && 運算符。位運算符出現在JavaScript中降低了這門語言的冗余,使得bug更容易被隱藏起來。

          function 函數對比 function 表達式

          JavaScript既有function語句,同時也有function表達式。這令人困惑,因為它們看起來好像就是相同的。一個function語句就是其值為一個函數的var語句的速記形式。

          下面的語句:

          function foo () {}

          意思相當于:

          var foo=function foo () {};

          我們建議使用的是第2種形式,因為它能明確表示foo是一個包含一個函數值的變量。要用好這門語言,理解函數就是數值是很重要的。

          function語句在解析時會發生被提升的情況。這意味著不管function被放置在哪里,它會被移動到被定義時所在作用域的頂層。這放寬了函數必須先聲明后使用的要求,而我認為這會導致混亂。在if語句中使用function語句也是被禁止的。結果表明大多數的瀏覽器都允許在if語句里使用function語句,但它們在解析時的處理上各不相同。這就造成了可移植性的問題。

          一個語句不能以一個函數表達式開頭,因為官方的語法假定以單詞 function 開頭的語句是一個function語句。解決方法就是把函數調用括在一個圓括號之中。

          1. (function () {

          2. var hidden_variable;

          3. //這個函數可能對環境有一些影響,但不會引入新的全局變量,

          4. })();

          于程序員來說,this這個關鍵字應該是再熟悉不過了,在C++、C#以及Java中,它的身影隨處可見,this也可以說是編程語言JavaScript的精髓,但是一定也有不少JavaScript開發者都遇到過this的陷阱。

          在C++、C#、Java中,this擁有十分明確的含義,就是單純指向當前的對象實例,但是,在動態編程語言JavaScript中,相同的this寫法,卻有不同的含義。

          JavaScript中的this代表函數運行時自動生成的一個內部對象,只能在函數內部使用。并且,你不能在創建統計this的時候就確定它,而應該在函數執行時進行確定,所以,一不留神,你就會掉進意想不到的坑!

          0、誰調用了就誰來負責

          我們先來看看代碼:

          var name='a';

          var obj={

          name: 'b',

          getName: function() {

          console.log(this.name);

          }

          };

          obj.getName(); // b

          var getName=obj.getName;

          getName(); // a

          var obj2=(function() {

          return function() {

          console.log(this.name);

          }

          })();

          obj2(); // a

          首先,obj.getName()打印出來b,因為,obj調用了getName(),所以其this指向obj,this.name就是b。

          其次,getName()打印出a的原因:理由是此時的obj并不調用getName(),而是全局變量window,因此,結果是a

          最后,obj2中,因為采用了立即執行函數,它返回一個函數,而當我們調用時,調用它的也是全局變量window,所以打印結果也是a。

          需要注意的是,匿名函數內的this是指向window的,更準確的說是指向調用者。

          1、必須了解new的過程

          function Test() {

          console.log(this.name);

          }

          Test(); // a

          var test=new Test(); // undefined

          function Test2() {

          this.name='c';

          }

          var test2=new Test2();

          console.log(test2.name); // c

          為什么這個例子最終打印出來的是c呢?這里new的過程不可忽略,new Test2() 其實執行了三步動作:

          首先,創建一個空對象obj(var obj={};),然后,將這個空對象的[[Prototype]](__proto__)成員指向了Test2函數對象prototype成員對象最后,將Test2函數對象的this指針替換成obj:

          obj.__proto__=Test2.prototype;

          Test2.call(obj);

          當沒有顯式返回值或者返回為基本類型、null時,默認將 this 返回(參考2)

          因此,在這個例子中,當你使用new的時候,函數內部的this指向已經改變了,不再指向window。

          主要應該搞清楚new的過程,然后就知道打印出c的原因了。

          2、奇怪的return

          看過上面的例子后,你是否覺得已經掌握了new的函數內的this指向?千萬別掉以輕心,在JavaScript中,多的是例外,如:

          function Test3() {

          this.name='d';

          return {};

          }

          var test3=new Test3();

          console.log(test3.name); // undefined

          function Test4() {

          this.name='d';

          return 1;

          }

          var test4=new Test4();

          console.log(test4.name); // d

          可以再試試return 'd' | null | undefined中的一個或更多類型。

          結論:如果return的是一個對象(null除外),那么this指向的這個對象,否則this依舊指向實例對象。


          主站蜘蛛池模板: 国产一区二区三区播放心情潘金莲 | 国产精品区一区二区三在线播放 | 亚洲国产精品自在线一区二区| 好爽毛片一区二区三区四无码三飞| 一区二区三区在线免费| 国产伦精品一区二区三区免费迷 | 精品国产一区二区三区在线观看| 亚洲午夜精品第一区二区8050| 亚洲午夜日韩高清一区| 日韩一区二区三区射精| 国产成人一区二区三区高清| 韩国女主播一区二区| 一区二区手机视频| 免费看AV毛片一区二区三区| 91精品乱码一区二区三区| 国产视频一区二区在线观看| 偷拍激情视频一区二区三区| 亚洲一区二区三区在线| 另类ts人妖一区二区三区| 在线日产精品一区| 99久久精品日本一区二区免费| 日韩精品区一区二区三VR| 精品国产日韩亚洲一区在线| 国产精品视频分类一区| 精品黑人一区二区三区| 中文字幕精品一区二区2021年| 日本一区午夜爱爱| 亚洲第一区香蕉_国产a| 国产激情无码一区二区| 无码日韩精品一区二区三区免费 | 国产剧情国产精品一区| 国产精品视频一区二区三区经 | 亚洲一区二区三区国产精品| 亚洲熟女乱综合一区二区| 国产日韩精品一区二区三区在线| 精品午夜福利无人区乱码一区| 亚洲午夜精品一区二区麻豆| 精品国产一区二区三区www| 福利一区在线视频| 伊人久久大香线蕉AV一区二区| 国产乱码一区二区三区|