網上看到一句話,匿名函數的執行是具備全局性的,那怎麼具備的全局性呢?閉包內部this的指向是window,爲何指向了window呢?下面經過js函數調用模式和部分案例分析了爲何確實如此
var obj = { val : 1, show : function(){alert(this.val);},//方法調用模式 outFunc : function(){ function innerFunc(){ console.log(this); } innerFunc(); //函數調用模式 } }; obj.innerFunc(); //在嚴格模式下,console.log(this)中的this爲undefined, //不然,console.log(this)中的this爲全局對象(瀏覽器中爲window) //下文講解爲何
當以new來調用一個函數時,即構造器模式。
當使用new調用時,發生這些事情:
建立一個鏈接到該函數prototype的新對象
將this綁定到建立的新對象上
函數結束時,若是沒有返回其它對象,就返回this,即新建立的對象。編程
var quo=function(string){ this.status=string; } quo.prototype.get_status=function(){ return this.status; } var qq=new quo("aaa"); alert(qq.get_status());
var myobject={}; var sum = function(a,b){ return a+b; }; var sum2 = sum.call(myobject,10,30); //var sum2 = sum.apply(myobject,[10,30]); alert(sum2);
var person = { name :'one', sayOne:function () {//方法調用模式 console.log(this.name) }, sayTwo:function () {//函數調用模式 return function () { console.log(this.name) } }, wrap: function(){//函數調用模式,匿名函數的執行環境具備全局性的由來 (function (){ console.log(this.name) })() } } person.sayOne()//one sayOne調用者是person對象,因此this指向person;(方法調用模式) person.sayTwo()()//window 返回的匿名函數在全局執行因此是window(函數調用模式) person.wrap()//window 語言就是這樣設計的,也是匿名函數具備全局性的由來(函數調用模式)
var div=document.getElementById("one"); function f2(){ console.log(this) } div.onclick =function () { console.log(this)//one那個節點 f2()//window(函數調用模式) }
1.throttle函數的執行環境具備全局性,內部this一般是指向window的,而後返回一個匿名函數。
2.返回的匿名函數綁定了事件,this指向監聽的元素(document)
3.fn其實與上面返回匿名函數造成了閉包,且fn也實際上是一個匿名函數,匿名函數的執行具備全局性,fn內部this應該指向window
4這裏用apply修正this指向,使fn內部的this從新指向document瀏覽器
function throttle(fn, delay) { console.log(this)//window // 記錄上一次函數觸發的時間 var lastTime = 0; return function() { // 記錄當前函數觸發的時間 var nowTime = Date.now(); if(nowTime - lastTime > delay) { /* fn(); console.log(this)//document */ fn.apply(this)// 修正this指向問題 console.log(this)//document // 同步時間 lastTime = nowTime; } } } document.onscroll = throttle(function() { /*console.log(this)//window*/ console.log(this)//document console.log('scroll事件被觸發了' + Date.now()) }, 1000)
var name = "global"; var foo = { name: "foo", getName : function(){ console.log(this.name); } } var bar = { name: "bar", getName : function(){ return (function(){ console.log(this.name); })(); } } foo.getName(); //foo foo.getName.call(bar); //bar foo.getName.call(this); //global foo.getName.call(window); //global (function(){ console.log(this.name) }.bind(bar))(); //bar (function(){ console.log(this.name) }.bind())(); //global