资讯专栏INFORMATION COLUMN

匿名函数以及闭包内部this指向(函数调用模式的问题)

remcarpediem / 1382人阅读

摘要:网上看到一句话,匿名函数的执行是具有全局性的,那怎么具有的全局性呢闭包内部的指向是,为什么指向了呢下面通过函数调用模式和部分案例分析了为什么确实如此函数调用的模式方法调用模式和函数调用模式如果一个函数被设置为一个对象的属性,则称它为一个方法

网上看到一句话,匿名函数的执行是具有全局性的,那怎么具有的全局性呢?闭包内部this的指向是window,为什么指向了window呢?下面通过js函数调用模式和部分案例分析了为什么确实如此
1.js函数调用的模式 1.方法调用模式和函数调用模式

如果一个函数被设置为一个对象的属性,则称它为一个方法。当通过对象对其进行调用时,即this的方法调用模式。在方法调用模式下,函数中的this指向该函数所属的对象。

当一个函数并非对象的属性,而是直接作为函数进行调用时,为函数调用模式。此模式来调用函数的时候,this绑定的是全局对象。这是语言设计的一个错误。倘若语言设计正确,那么当内部函数被调用时,this应该仍然绑定到外部函数的this变量。这个设计错误的后果就是方法不能利用内部函数来帮助它工作,因为内部函数的this被绑定了错误的值,所以不能共享该方法对对象的访问权

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)
//下文讲解为什么
2.构造器调用模式

当以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());
3.上下文调用模式(call,apply)
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);
2.闭包和匿名函数案例分析(这两种都是函数调用模式)
    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 语言就是这样设计的,也是匿名函数具有全局性的由来(函数调用模式)
3.事件监听内部调用方法案例分析
    var div=document.getElementById("one");
    function f2(){
    console.log(this)
    }
    div.onclick =function () {
        console.log(this)//one那个节点
        f2()//window(函数调用模式)
    }
4.综合应用:函数节流案例分析

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)
5.参考JS高级编程的案例解决问题
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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/114607.html

相关文章

  • 匿名函数以及闭包内部this指向函数调用模式问题

    摘要:网上看到一句话,匿名函数的执行是具有全局性的,那怎么具有的全局性呢闭包内部的指向是,为什么指向了呢下面通过函数调用模式和部分案例分析了为什么确实如此函数调用的模式方法调用模式和函数调用模式如果一个函数被设置为一个对象的属性,则称它为一个方法 网上看到一句话,匿名函数的执行是具有全局性的,那怎么具有的全局性呢?闭包内部this的指向是window,为什么指向了window呢?下面通过js...

    yy736044583 评论0 收藏0
  • 匿名函数以及闭包内部this指向函数调用模式问题

    摘要:网上看到一句话,匿名函数的执行是具有全局性的,那怎么具有的全局性呢闭包内部的指向是,为什么指向了呢下面通过函数调用模式和部分案例分析了为什么确实如此函数调用的模式方法调用模式和函数调用模式如果一个函数被设置为一个对象的属性,则称它为一个方法 网上看到一句话,匿名函数的执行是具有全局性的,那怎么具有的全局性呢?闭包内部this的指向是window,为什么指向了window呢?下面通过js...

    _Zhao 评论0 收藏0
  • 面试官问我:什么是JavaScript闭包,我该如何回答

    摘要:到底什么是闭包这个问题在面试是时候经常都会被问,很多小白一听就懵逼了,不知道如何回答好。上面这么说闭包是一种特殊的对象。闭包的注意事项通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。从而使用闭包模块化代码,减少全局变量的污染。 闭包,有人说它是一种设计理念,有人说所有的函数都是闭包。到底什么是闭包?这个问题在面试是时候经常都会被问,很多小白一听就懵逼了,不知道如何回答好。这个...

    BenCHou 评论0 收藏0
  • 《JavaScript高级程序设计》(第3版)读书笔记 第7章 函数表达式

    摘要:定义函数表达式的方式有两种函数声明。不过,这并不是匿名函数唯一的用途。可以使用命名函数表达式来达成相同的结果闭包匿名函数和闭包是两个概念,容易混淆。匿名函数的执行环境具有全局性,因此其对象通常指向通过改变函数的执行环境的情况除外。 定义函数表达式的方式有两种: 函数声明。它的重要特征就是 函数声明提升(function declaration hoisting) 即在执行代码之前会...

    邹立鹏 评论0 收藏0

发表评论

0条评论

remcarpediem

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<