`
lucane
  • 浏览: 121707 次
  • 性别: Icon_minigender_1
  • 来自: 江湖
社区版块
存档分类
最新评论

改变函数执行的上下文

阅读更多
参考阅读:js教程:javascript作用域(Scope)

JavaScript中this代表的是运行时的对象,是正在调用代码的对象

在浏览器环境中运行需要把println函数改成alert或者console.log

function gf() {println(this)}


运行这段代码输出:[object global]

下面这段代码人为改变了代码执行的上下文,this也就代表着不同的对象
var obj1 = {count:1};
var obj2 = {count:6};

function foo(factor) {this.count * factor}

foo.call(obj1, 8); // 1 * 8
foo.call(obj2, 8); // 6 * 8


再看
Prototype的bind方法代码
Function.prototype.bind = function() {
    var __method = this, args = $A(arguments), object = args.shift(); // Important
    return function() {
        return __method.apply(object, args.concat($A(arguments)));
    }
}

// 上面这种方法没怎么明白,把arguments转换成Array,然后把执行函数绑定在第一个方法的参数上(把绑定的对象提取出来)
// 绑定参数又增加args.concat($A(arguments)),这多出来的几行代码是什么意图?
// 原来这样是为了
// 在bind函数执行的时候可以添加一次参数
// 然后在后期bind返回的函数执行的时候又可以添加一次参数
// 这样在函数执行的上下文变化时还能“记忆”之前的参数,这就是JS的必包特性
// http://mengjiaoyao.blog.163.com/blog/static/298416192009113102149773/


// 将传入的对象转化成Array
var $A = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) {
    return iterable.toArray();
  } else {
    var results = [];
    for (var i = 0, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}


早期的Prototype中bind方法更简单明了
Function.prototype.bind = function(object) {
    var method = this; // Important
    return function() {
        method.apply(object, arguments);
    }
}


改写我们上面代码
var foo1 = foo.bind(obj1);
foo1(8);


两次传参的调用代码
var obj1 = {count:1};
var obj2 = {count:6};

function foo(a,b,c) {println(this.count * a * b * c)}


var foo1 = foo.bind(obj1, 2);
var foo2 = foo.bind(obj2, 3);
foo1(5,6);
js>60 // 1 * 2 * 5 * 6
foo2(7,8);
js>1008 // 6 * 3 * 7 * 8


这就是改变函数执行上下文+记忆不同上下文之间参数的结果


如果不想用prototype这种方式的写法的话,可以参考如下代码
var gbind = function(o, f) {
    return function() {
        return f.apply(o, arguments);
    }
};

这种写法如果需要支持更复杂的参数传递的话,想想该怎么写?

虽然看不懂,但每次想这个问题还得看一遍
引用
A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).


以下纯淡腾乱作,请蒙上眼睛
// another version xscript%#%live.com
// 实在没有必要这么写
// bindAsEventListener()返回的函数必须至少带一个参数,那就是event,否则在FF无法运行
Function.prototype.bindAsEventListener = function() {
    var __method = this, args = $A(arguments), object = args.shift();
    return function() {
        var a = $A(arguments), e, evts;
        var __e_m = "警告,您的浏览器必须指定第一个参数类型为事件!";
        // 如果后期传入了参数
        // alert(a.length); // IE和W3C输出的不一样,应该好好学学,理解
        if(0 < a.length) {
            e = a[0];
            // alert(typeof e);
            // alert(e.type);
            // 如果是事件,判断对象是否事件还有待改进
            // 
            if("object" == typeof e && !!e.type && !!e.srcElement) {
                a.shift();
                evts = [e || window.event];
            } else if(!window.event) { // 而且window.event都无法捕捉到
                true == !!console.log ? console.log(__e_m) : alert(__e_m);
                return false;
            } else {
	            evts = [window.event];
            }
        } else {
            if(!!window.event) {
                evts = [window.event]; 
            } else {
                true == !!console.log ? console.log(__e_m) : alert(__e_m);
                return false;
            }
        }
        return __method.apply(object, evts.concat(args).concat(a));
    }
}
分享到:
评论

相关推荐

    深入理解JavaScript执行上下文、函数堆栈、提升的概念.pdf

    2. 函数执行上下文:每当函数被调用时,都会创建一个新的执行上下文,用于函数的局部变量、参数以及函数声明。 3. Eval 执行上下文:使用 `eval()` 函数时创建的执行上下文,这个用法不推荐,因为它会有安全风险和...

    js中call与apply的用法小结.docx

    总结来说,`call`和`apply`在JavaScript编程中扮演了关键角色,它们提供了改变函数执行上下文的能力,从而支持了函数绑定、继承和参数灵活传递等高级功能。理解并熟练运用这两个方法对于提升JavaScript编程技能至关...

    96道web前端面试题.pdf

    10. call和apply的使用:这两个方法都是用来改变函数执行上下文的,它们的共同点和区别在于如何接收参数。 通过这些内容,应聘者可以更好地理解前端面试的考察重点,从而针对性地准备和展示自己的技能。此外,对于...

    JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析

    首先,执行上下文分为全局执行上下文和局部(函数)执行上下文。全局执行上下文是程序的起点,它是执行上下文堆栈的底部,始终存在。在这个上下文中,全局变量和函数被定义。例如,当加载JavaScript文件或在HTML中的...

    JS ES6中setTimeout函数的执行上下文示例

    而在ES6中,箭头函数的引入改变了这个规则,setTimeout中的箭头函数执行上下文与定义箭头函数的上下文相同,因此this的值是绑定到定义它时所在的函数的this上。了解这些知识点对于编写可预测且可靠的JavaScript代码...

    新编辑的五日学会JS教程

    3. **this与call/apply/bind**:学习this的指向,以及如何改变函数执行上下文。 第四天:异步编程与事件循环 1. **回调函数**:了解异步编程的基础,如何使用回调解决异步问题。 2. **Promise**:学习Promise的创建...

    字节前端第一期面试题(1).pdf

    call和apply都是改变函数执行上下文的方法,call接受参数列表,apply接受参数数组,性能差异不大。 39. 使用1x1像素的透明GIF图片进行数据埋点的原因: 因为GIF图片体积小,加载速度快,不易引起用户注意,适合用于...

    jquery中文手册、jquery中文教程、javascript框架、jquery

    - **上下文和作用域**:理解`this`关键字在jQuery方法中的变化,以及如何使用`$.proxy()`或`.call()`、`.apply()`来改变函数执行上下文。 - **插件机制**:jQuery的可扩展性体现在其插件系统,了解如何编写和使用...

    js代码-手写实现 new 手写实现 call 理解执行 call 后输出的是函数执行的值,并且传进去的对象执行了相应函数,属性会发生变化。

    总结来说,`new`和`call`都是JavaScript中改变函数执行上下文的关键工具。`new`用于创建对象实例并设置`this`,而`call`则允许我们在任何上下文中直接调用函数。通过手写实现这两个方法,我们可以更深入地理解它们的...

    this和执行上下文实现代码

    2. **函数执行上下文**:每当调用一个函数时,都会创建一个新的执行上下文。函数执行上下文中的`this`、参数、以及函数内的局部变量都会在此环境中定义。 3. **作用域链**:与执行上下文相关的还有作用域链,它决定...

    易语言线程上下文注入源码

    在易语言中实现线程上下文注入,可以让我们在不修改程序本身的情况下,动态地改变程序的行为。 线程上下文注入的核心概念是线程上下文(Thread Context)。在Windows操作系统中,线程上下文包含了执行线程的所有...

    详解VC++设备上下文DC

    通过调用`GetDC`函数,可以在构造函数中获取窗口的显示设备上下文,然后在其上执行绘制操作。 3. **CMetaFileDC**:这个类用于创建元文件,即记录了绘制动作的文件,可以在不同的设备上下文中回放这些动作。 通过...

    11-this:从JavaScript执行上下文的视角讲清楚this_For_vip_user_0011

    当使用`new`关键字调用函数时,会创建一个新的执行上下文,`this`会指向这个新实例。 ```javascript function Person(name) { this.name = name; } var person = new Person("Alice"); console.log(person....

    linux目录操作函数汇总 遍历,改变路径等

    Linux作为一套开源操作系统,广泛应用于服务器、桌面和嵌入式系统。...在实际编程中,需要根据具体需求和上下文选择合适的系统调用函数,同时还要注意错误处理和异常情况的处理,以确保应用程序的健壮性和安全性。

    编辑框上下文菜单演示程序代码

    3. **显示上下文菜单**:使用`CMenu::LoadMenu`函数加载资源中的菜单,然后用`TrackPopupMenu`函数在鼠标点击位置显示菜单。`TrackPopupMenu`允许你在用户选择菜单项后自动隐藏菜单。 4. **处理菜单选择**:为每个...

    JS 四种函数调用模式

    这两个方法允许我们动态地改变函数的执行上下文,即 `this` 的值。`call` 和 `apply` 都能立即调用一个函数,但它们接受参数的方式不同。`call` 接受一系列参数,而 `apply` 接收一个包含参数的数组。 ```javascript...

    js中Function引用类型常见有用的方法和属性详解

    总结来说,JavaScript的Function类型提供了丰富的功能,包括但不限于动态创建函数、改变函数执行上下文、访问函数调用相关信息等。理解和掌握这些特性对于编写高效的JavaScript代码至关重要。希望这篇文章能帮助你更...

    javascript之bind使用介绍

    Bind 方法的出现,为开发者提供了一种改变函数执行上下文(也就是 this 指向)的方法,并且可以延迟函数的执行。 在详细介绍 bind 方法之前,我们先回顾一下 apply 和 call 这两个与 bind 相关的方法。apply 和 ...

Global site tag (gtag.js) - Google Analytics