摘要:系列系列列表從看一與箭頭函數從看二函數傳參模式與的上一篇說到,對做了以下限定。是另外一個變量,指向不同的值,而這兩個值有相同的類型。函數中,和指向同一個值,更改的就等于更改了的??梢杂酶倪M問題是這個在嚴格模式下不能運行。
系列
系列列表:
從use strict看JS(一):this與箭頭函數
從use strict看JS(二):函數傳參模式與arguments
上一篇說到,use strict對arguments做了以下限定
arguments。不允許對arguments賦值。禁止使用arguments.callee。arguments不再追蹤參數的變化
這是為什么呢?如果你明白下面兩個例子就不用看這篇文章了~
arguments傳的是“值”function notChangeName(obj){ obj="change"; } function changeName(obj){ obj.name="change"; } var dog={ name:"dog" }; notChangeName(dog); //輸出Object {name: "dog"},沒改變 console.log(dog); changeName(dog); //輸出Object {name: "change"},改了 console.log(dog); //經典例子,JavaScript高級程序設計的例子 function setName(obj){ obj.name="doge"; obj=new Object(); obj.name="cat"; } var person={}; setName(person); //doge console.log(person.name);嚴格模式下arguments會保持對同一“值”的引用
function notChangeName(name){ "use strict"; name="cat"; // 嚴格模式輸出dog,非嚴格輸出cat console.log(arguments[0]); } function changeName(obj){ "use strict"; obj.name="cat"; // 輸出cat console.log(arguments[0].name); } notChangeName("dog"); changeName({name:"dog"}); function dog(){ // "use strict"; //嚴格模式SyntaxError,非嚴格輸出"a" arguments="a"; console.log(arguments); } dog();arguments & js的變量、值、類型 js的變量、值、類型
js一個變量對應一個值,一個值對應一種類型;而一種類型對應多個值,一個值對應多個變量。
字符串的值不能改變,但能讓變量指向不同的值
舉兩個栗子:
no1.
var dog={ } var cat=dog; dog.name="doge"; var third={ name:"the third man" } // 輸出doge console.log(cat.name);
上述例子中,dog和cat是不同的變量,但指向同一個值,所以dog改變會反應到cat上。third是另外一個變量,指向不同的值,而這兩個值有相同的類型。如下圖
no2.
var str="doge"; // 輸出o console.log(str[1]); str[1]="c"; // 輸出o,字符串的值不能改變 console.log(str[1]); str="cat"; // 輸出c,變量指向了不同的值 console.log(str[0]);arguments傳的是值
所以,在前面的例子中,notChangeName函數內部將變量obj指向不同的值,外部的dog指向同一個值且值未發生變化。因而不能改變dog的name。
changeName函數中,obj和dog指向同一個值,更改obj的name就等于更改了dog的name。
JavaScript高級程序設計的例子同理。如下:
function notChangeName(obj){ obj="change"; } function changeName(obj){ obj.name="change"; } var dog={ name:"dog" }; notChangeName(dog); //輸出Object {name: "dog"},沒改變 console.log(dog); changeName(dog); //輸出Object {name: "change"},改了 console.log(dog); //經典例子,JavaScript高級程序設計的例子 function setName(obj){ obj.name="doge"; obj=new Object(); obj.name="cat"; } var person={}; setName(person); //doge console.log(person.name);
use strict下的arguments會保持對“值”的引用,因而arguments變量是不能被重新賦值的,如果強制賦值呢?比如arguments="a",那就強制報錯,沒得商量。
也是因為保持對“值”的引用,arguments不再追蹤參數的變化,但如果參數是obj且改變的是“值”,而不是重新賦值,那就不一樣了。如下:
function notChangeName(name){ "use strict"; name="cat"; // 嚴格模式輸出dog,非嚴格輸出cat console.log(arguments[0]); } function changeName(obj){ "use strict"; obj.name="cat"; // 輸出cat console.log(arguments[0].name); } notChangeName("dog"); changeName({name:"dog"}); function dog(){ // "use strict"; //嚴格模式SyntaxError,非嚴格輸出"a" arguments="a"; console.log(arguments); } dog();面試會考:arguments不是數組
這就是一個點而已,arguments不是數組,是個類數組對象,沒有數組的push、pop、map那些方法,那如何把它變為數組呢?循環遍歷一遍也是可以的,arguments有長度,但有更簡單的方法,如下:
function argToArr(index){ var newArg=Array.prototype.slice.apply(arguments); newArg.push(2); } argToArr(1);
為何不直接
arguments=Array.prototype.slice.apply(arguments);
因為現在很多都用use strict了,這個會報錯,還不知道為何會報錯的再看一遍文章哈,自覺點
最后談談arguments.callee這個用來干啥呢,它能在函數內部調用自己,常用來解耦和。比如寫個斐波那契數列函數
function fib(n){ if(n===1||n===2){ return 1; } return fib(n-1)+fib(n-2); }
這個問題在哪呢,耦合性太強,改了外層的fib,內部函數名稱也得改??梢杂胊rguments.callee改進
function fibArg(n){ if(n===1||n===2){ return 1; } return arguments.callee(n-1)+arguments.callee(n-2); }
問題是這個在嚴格模式下不能運行。不繞了,來個終極方法
var fib=(function f(n){ "use strict"; if(n===1||n===2){ return 1; } return f(n-1)+f(n-2); })
這種模式之后還會涉及,跟立即執行函數類似,jQuery這些也用了,以后再聊~
等等好像沒談為何要這樣限定arguments!
夜已深,就不繼續悟道了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82467.html
摘要:其次,指向有一個好處,構造函數一般不要直接運行,那要是強行運行呢指向會給添加許多屬性,有擾亂命名空間之嫌,指向之后,你強行運行我就強行報錯會給增加屬性,改成嚴格模式就會當然,不能解決所有問題,所以有了箭頭函數參考嚴格模式詳解 上github看原文:點一下 系列 一日,見use strict,冥想許久…… 系列列表:從use strict看JS(一):this與箭頭函數從use stri...
摘要:主要知識點有函數參數默認值剩余參數擴展運算符屬性塊級函數箭頭函數以及尾調用優化深入理解筆記目錄函數的默認參數在中,我們給函數傳參數,然后在函數體內設置默認值,如下面這種方式。擁有方法的函數被稱為構造器。 主要知識點有:函數參數默認值、剩余參數、擴展運算符、new.target屬性、塊級函數、箭頭函數以及尾調用優化showImg(https://segmentfault.com/img/...
摘要:錯誤的寫法錯誤的寫法中的構造函數新增了支持默認參數和不定參數。箭頭函數的簡單理解箭頭函數的左邊表示輸入的參數,右邊表示輸出的結果。但是有了尾調用優化之后,遞歸函數的性能有了提升。 作為前端切圖仔,越發覺得自己離不開函數了。 說到JavaScript函數,腦子里都是匿名函數、普通函數、閉包函數、構造函數......然后還能說出一大堆函數的概念。如果你達到這個水平,那么函數對你來說沒有難度...
摘要:作為對象原型鏈的終點。調用函數時,應該提供的參數沒有提供,該參數等于。它可以用于引用該函數的函數體內當前正在執行的函數。 一 JS 二 CSS 一 JS ==和===的區別 ===叫做嚴格運算符 ==叫做相等運算符嚴格運算符比較時不僅僅比較數值還要比較數據類型是否一樣相等運算符在比較相同類型的數據時,與嚴格相等運算符完全一樣。 在比較不同類型的數據時,相等運算符會先將數據進行類型轉換,...
閱讀 2234·2021-11-16 11:44
閱讀 641·2019-08-30 15:55
閱讀 3271·2019-08-30 15:52
閱讀 3595·2019-08-30 15:43
閱讀 2196·2019-08-30 11:21
閱讀 435·2019-08-29 12:18
閱讀 1945·2019-08-26 18:15
閱讀 468·2019-08-26 10:32