【javaScript】早绑定和迟绑定

javaScript会在调用时会设置执行上下文“this”的值。

一些经常使用的错误例子

我们举一个例子,给一个Menu构造函数,来接受一个元素来创建一个菜单。

function Menu(elem){

    //...

}

//使用
var elem = document.getElementById(‘something‘) // a DOM element
var menu = new Menu(elem);

当我们在构造函数里调用setTimeout时,你也许想引用这个menu对象,我们可能会像如下这样做:

function Menu(elem){

    setTimeout(function(){
        alert(this);    //window, not menu!

    }, 1000);

}

new Menu(document.createElement(‘div‘));

但是this指向的是window,因为setTimeout总是在window上下文环境中执行,再看下面的例子:

function Menu(elem){

    elem.onclick = function(){
        alert(this);    //elem, not menu!
    }

}

元素事件处理器将this设置为指向elem而不是menu。

私有方法或本地函数:本地函数经常被用来作为私有方法。

function Menu(elem){

    function privateMethod(){
        alert(this);    //window,not menu!
    }

    //调用私有方法
    privateMethod();

}

new Menu(document.createElement(‘div‘));

调用私有方法,this也是指向window。

用var self = this来绑定

首先,我们可以在闭包中存储this。

下面的例子中,将this赋值给self,用self来代替this的使用。

function Menu(elem){
    var self = this;
    setTimeout(function(){
        alert(self);    //object, menu!
    }, 1000);
}

new Menu(document.createElement(‘div‘));
早绑定

我们需要用到一个帮助函数bind来强制绑定到this。

function bind(func, fixThis){
    return function(){
        return func.apply(fixThis, arguments);
    }
}

function Menu(elem){
    elem.onclick = bind(function(){
        alert(this);    //object!(menu)
    },this);
}

其实原生的方法Function.prototype.bind已经实现了,目前大多数浏览都支持,如果不支持我们也可以进行模拟。

Function.prototype.bind = Function.prototype.bind || function(fixThis){

    var func = this;
    return function(){
        return func.apply(fixThis, arguments);
    }
}

可能有些人觉得这样做污染了原生的属性,不推荐这种用法。但是改变Function.prototype有时也是能够接受的。它不会影响对象或数组的迭代,副作用非常小的。

如果用上面这种方法,那会简单很多。

setTimeout

function Menu(elem) {

  setTimeout(function() {
    alert(this)  // object! (menu)
  }.bind(this), 1000)

}

new Menu(document.createElement(‘div‘))

onclick

function Menu(elem) {

  elem.onclick = function() {
    alert(this)  // object! (menu)
  }.bind(this)

}

私有方法或本地方法

但是有点问题,在函数声明时不能调用bind,在函数表达式时是可以的。

function Menu(elem) {
  function privateMethod() {
    alert(this);
  }.bind(this); // syntax error, can‘t call method in-place
}

function Menu(elem) {
  var privateMethod = function() {
    alert(this);
  }.bind(this);

  privateMethod();
}

new Menu(document.createElement(‘div‘));
迟绑定

迟绑定的意思就是在调用时进行绑定,而早绑定是及时绑定,也就是在函数声明时就已经确定好了。

早绑定的问题

以下例子我们点击body后我们发现输出的不是"SuperMenu",而是"Menu"。

<!DOCTYLE HTML>
<html>
<body>
<script>
function bind(func, fixThis) {
    return function() {
        return func.apply(fixThis, arguments);
    }
}

function Menu(elem) {

    this.sayHi = function() { alert(‘Menu‘); }

    elem.onclick = bind(this.sayHi, this);
}

function SuperMenu(elem) {
    Menu.apply(this, arguments);

    this.sayHi = function() { alert(‘SuperMenu‘); }
}

new SuperMenu(document.body);
</script>
</body>
</html>

真正的晚绑定

这次我们看到了我们想要的结果,输出的是“SuperMenu"。关键一步是:fixThis[funcName]是动态从去获取对象的属性,当运行时改变该属性时也能正确执行调用。其实如果你目前用的是jquery库的话,$.proxy已经实现了早绑定和迟绑定,具体可以查看相关API。

<!DOCTYLE HTML>
<html>
<body>

<script>
function bindLate(funcName, fixThis) {
    return function() {
        return fixThis[funcName].apply(fixThis, arguments);
    }
}

function Menu(elem) {

    this.sayHi = function() { alert(‘Menu‘); }
    elem.onclick = bindLate(this.sayHi, this);
}

function SuperMenu(elem) {

    Menu.apply(this, arguments)
    this.sayHi = function() { alert(‘SuperMenu‘); }
}

new SuperMenu(document.body);

</script>
</body>
</html>

【javaScript】早绑定和迟绑定,码迷,mamicode.com

时间: 2024-08-08 09:42:37

【javaScript】早绑定和迟绑定的相关文章

早绑定和迟绑定技术的通俗分析

概念: 早绑定指的是在编译阶段进行绑定 迟绑定指的是运行阶段绑定 例子: Class Base { void fun(){} } Class Bind :Class Base { Void fun(){} } main() { Base base: base->fun(); Bind *tmp; tmp  = &base; tmp->fun(); } 上面的例子说明大家一个是不是有语法问题,其实我是故意的,fun函数被覆盖了 先来说说base->fun();是怎么一个过程吧. 程

Javascript实现简单的双向绑定

双向数据绑定指的是将对象属性变化绑定到UI,或者反之.换句话说,如果我们有一个拥有name属性的user对象,当我们给user.name赋予一个新值是UI也会相应的显示新的名字.同样的,如果UI包括了一个输入字段用来输入用户名,输入一个新的值会导致user对象中的那么属性发生变化. 双向数据绑定底层的思想非常的基本,它可以被压缩成为三个步骤: 我们需要一个方法来识别哪个UI元素被绑定了相应的属性 我们需要监视属性和UI元素的变化 我们需要将所有变化传播到绑定的对象和元素 虽然实现的方法有很多,但

JavaScript学习13:事件绑定

事件绑定分为两种:一种是传统事件绑定(内联模型.脚本模型),一种是现代事件绑定(DOM2级模型).现代事件绑定在传统绑定的基础上为我们提供了更强大更方便的功能. 传统事件绑定的问题 因为内联模型很少用,这里不做讨论.先来看一下脚本模型,将一个函数赋值给一个事件处理函数. <span style="font-size:18px;">var box=document.getElementById('box'); box.onclick=function(){ alert('Li

javascript - 工作笔记 (事件绑定)

背景: 目前所做的项目,只能使用的是原生的javascript.对于javascript的事件绑定想必大家都懂得语法: 1,在标签中使用属性调用方法:<div onclick="AAAA();"></div> 2,在javascript中对标签对象绑定数据: <div id="test"></div> var item = document.getElementById("test"); item.

java之多态(Polymorphic)、动态绑定(Dynamic Binding)、迟绑定(Late Binding)

今天,我们来说说java面向对象最核心的东西,多态.通过多态可以使我们的程序可复用性达到极致,这就是我们为什么要学多态的原因. “多态”(Polymorphic)也叫“动态绑定”(Dynamic Binding)同时也叫“迟绑定”(Late Binding). 动态绑定是指“在执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际类型调用其相应的方法.” 程序代码: public class TestPolymorphic{ public static void main(String a

JavaScript学习总结4--事件绑定

所谓事件,就是指我们在页面上的一些交互操作,比如单击鼠标,按下键盘等等 当我们需要操作某些元素使它有一定的交互效果时,就需要给相应的元素绑定事件处理函数 事件绑定分为3种,分别是HTML内嵌(不推荐).传统事件绑定(也叫DOM0级事件绑定).以及DOM2级事件绑定 1.HTML内嵌 <!--省略之前代码--> <body> <a href="#" onclick="fnEvent()">点我触发事件</a> </

.Net中的早期绑定和后期绑定(二)

上篇介绍了.Net中绑定的故事背景,在文章的末尾引出了"早期绑定和后期绑定",那么本文就针对.Net中的绑定做一个简单的介绍. 早期绑定 早期绑定:如果在编译时 .Net 能够知道属性或方法所属的对象,就可以预先查找该成员在类型库中的 DispID 或 vtable 地址.这样就无须在运行时调用 GetIDsOfNames.当显式声明了变量的类时,例如 As Class,该变量就只能存放该类的对象的引用..Net 就可以为该变量调用的所有属性和方法使用早期绑定. 后期绑定 在.Net中

前期绑定和后期绑定

程序绑定的概念:绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定 静态绑定:在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现.例如:C.针对java简单的可以理解为程序编译期的绑定:这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定 动态绑定:后期绑定:在运行时根据具体对象的类型进行绑定.若一种语言实现了后期绑定,同时必 须提供一些机制,可在运行期间判断对

什么样的局域网需要IP-MAC绑定?IP-MAC绑定的好处。

1. 为什么要进行IP-mac绑定? IP-MAC绑定是网络管理的一个重要手段,在局域网内启用IP-MAC绑定,可以给您带来如下好处: 只有通过绑定的设备才可以接入网络,从而有效的防止了私接设备. 大部分上网和流控策略都是基于IP地址的,需要绑定IP和MAC才可以更好的应用上网策略. 实现有效的上网记录和上网统计.如果不绑定,那么记录统计不能有效的定位到具体用户. 节省IP资源,防止IP盗用. 减少ARP攻击,杜绝IP地址冲突,从而提高网络的稳定性. 所以,对于企业的办公局域网来说,IP-MAC