javascript高级知识点——指定上下文实现

代码信息来自于http://ejohn.org/apps/learn/。

当我们将一个对象的点击事件绑定到一个事件触发元素时会发生什么?

<ul id="results">
</ul>
<script>
var Button = {
  click: function(){
    this.clicked = true;
  }
}; 

var elem = document.createElement("li");
elem.innerHTML = "Click me!";
elem.onclick = Button.click;
document.getElementById("results").appendChild(elem); 

elem.onclick();
console.log( elem.clicked, "clicked属性被设置在点击的元素上面了" );
</script>

因为elem.onclick(),调用onclick时,this指向调用它的对象,也就是elem,所以发生错误。

我们需要固定上下文为原先的对象

function bind(context, name){
  return function(){
    return context[name].apply(context, arguments);
  };
} 

var Button = {
  click: function(){
    this.clicked = true;
  }
}; 

var elem = document.createElement("li");
elem.innerHTML = "Click me!";
elem.onclick = bind(Button, "click");
document.getElementById("results").appendChild(elem); 

elem.onclick();
console.log( Button.clicked, "点击属性被设置在了原先的对象上面" );

修改方法以适应所有的函数

Function.prototype.bind = function(object){
  var fn = this;
  return function(){
    return fn.apply(object, arguments);
  };
}; 

var Button = {
  click: function(){
    this.clicked = true;
  }
}; 

var elem = document.createElement("li");
elem.innerHTML = "Click me!";
elem.onclick = Button.click.bind(Button);
document.getElementById("results").appendChild(elem); 

elem.onclick();
console.log( Button.clicked, "点击属性被设置在原先对象上面" );

最终目标,考虑到带参数的函数

Function.prototype.bind = function(){
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function(){
    return fn.apply(object,
      args.concat(Array.prototype.slice.call(arguments)));
  };
}; 

var Button = {
  click: function(value){
    this.clicked = value;
  }
}; 

var elem = document.createElement("li");
elem.innerHTML = "Click me!";
elem.onclick = Button.click.bind(Button, false);
document.getElementById("results").appendChild(elem); 

elem.onclick();
console.log( Button.clicked === false, "属性被设置在原先对象上面" )
时间: 2024-10-27 10:44:06

javascript高级知识点——指定上下文实现的相关文章

javascript高级知识分析——上下文

如果函数是一个对象的属性,那么它可以? var katana = { isSharp: true, use: function(){ this.isSharp = !this.isSharp; } }; katana.use(); console.log( katana.isSharp );//false; 在javascript中,函数的内部,this默认指向调用它的对象.本例katana.use(),函数use被对象katana调用,所以在函数内部,this.isSharp可以操作katan

javascript高级知识点——内置对象原型

代码信息来自于http://ejohn.org/apps/learn/. 可以修改内置对象的方法. if (!Array.prototype.forEach) { Array.prototype.forEach = function(fn){ for ( var i = 0; i < this.length; i++ ) { fn( this[i], i, this ); } }; } ["a", "b", "c"].forEach(fun

javascript高级知识点——函数的长度

代码信息来自于http://ejohn.org/apps/learn/. 函数的长度属性如何工作? function makeNinja(name){} function makeSamurai(name, rank){} console.log( makeNinja.length == 1, "只定义了一个形参" ); console.log( makeSamurai.length == 2, "定义了两个形参" ); 很清楚,函数的长度就是定义形参的个数. 我们

javascript高级知识点——继承

代码信息来自于http://ejohn.org/apps/learn/. 继承是如何工作的 function Person(){} function Ninja(){} Ninja.prototype = new Person(); var ninja = new Ninja(); console.log( ninja instanceof Ninja, "ninja自动接收Ninja.prototype里的属性" ); console.log( ninja instanceof Pe

javascript高级知识点——函数原型

代码信息来自于http://ejohn.org/apps/learn/. 向函数的原型中添加方法 function Ninja(){} Ninja.prototype.swingSword = function(){ return true; }; var ninjaB = new Ninja(); console.log( ninjaB.swingSword(), "Method exists and is callable." ); 通过实例化对象可以访问,因为构造函数实例化的对象

javascript高级知识点——实例类型

代码信息来自于http://ejohn.org/apps/learn/. 分析一下对象的结构 function Ninja(){} var ninja = new Ninja(); console.log( typeof ninja == "object", "仍然是对象" ); console.log( ninja instanceof Ninja, "是Ninja的实例" ); console.log( ninja.constructor =

javascript高级知识点——临时作用域

代码信息来自于http://ejohn.org/apps/learn/. 自执行,临时,函数 (function(){ var count = 0; })(); 这是一个简单的自执行匿名函数. 做一个点击计数 document.addEventListener("click", (function(){ var numClicks = 0; return function(){ alert( ++numClicks ); }; })(), false); 关键代码是,自执行匿名函数,返

javascript高级知识点——memoization

memoization是一种非常有用的优化技术,它缓存特定输入产生的相应结果.这样麻烦的查找和迭代计算可以尽可能的减少. 它基本的思想是针对特定的输入,已经计算过的结果都是通过缓存当中的数据直接返回而不是经过重复的计算. 实现记忆函数 我们可以简单的将memoization理解为记忆函数经过特定输入产生的结果. 下面是一种基本简单且实用的实现方法,可以很清晰的显示记忆函数的结构 function memoize( fn ) { return function () { // 将参数转为数组 va

《javascript高级程序设计》第五章知识点总结

第五章知识点总结 1.object类型 访问对象的方法:①点表示法        (people.name) :      ②方括号表示法         (people[name]). 常用方法:hasOwnProperty()         用于检查给定属性在当前对象实例中是否存在 isPrototypeOf()              用于检测传入的对象是否传入对象原型 toString()                        返回对象的字符串表示 valueOf()