标签:
Function对象(apply、call、bind)
本文参考MDN做的详细整理,方便大家参考[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
Function 构造器会创建一个新的 Function 对象。 在 JavaScript 中每个函数都是一个Function对象。
构造器
new Function ([arg1[, arg2[, ...argN]],] functionBody)
例:var adder = new Function("a", "b", "return a + b"); // 创建了一个能返回两个参数和的函数
adder(2, 6); // 8
使用Function构造器生成的Function对象是在函数创建时解析的。这比你使用函数声明或者函数表达式(function)并在你的代码中调用更为低效,因为使用后者创建的函数是跟其他代码一起解析的。
所有被传递到构造函数中的参数,都将被视为将被创建的函数的参数,并且是相同的标示符名称和传递顺序。
使用Function构造器生成的函数,并不会在创建它们的上下文中创建闭包;它们一般在全局作用域中被创建。当运行这些函数的时候,它们只能访问自己的本地变量和全局变量,不能访问Function构造器被调用生成的上下文的作用域。这和使用带有函数表达式代码的 eval 不同。
属性:
length 是函数对象的一个属性值,指明该函数期望多少个参数,即形参的个数。数量不包括剩余参数。相比之下, arguments.length 是函数被调用时实际传参的个数。
方法
Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
在一个对象thisArg的上下文中应用另一个对象的方法;参数能够以列表形式传入,即在使用一个指定的this值(thisArg)和若干个指定的参数值的前提下调用某个函数或方法。
function greet() { var reply = [this.person, ‘Is An Awesome‘, this.role].join(‘ ‘); console.log(reply); } var a = { person: ‘Douglas Crockford‘, role: ‘Javascript Developer‘ }; greet.call(a); // Douglas Crockford Is An Awesome Javascript Developer
function Food(name, price) { Product.call(this, name, price); this.category = ‘food‘; }
for(var i =0;i<10;i++){ setTimeout(function(){ console.log(i); }.call(null,i),0) } //可以顺利输出0~9,如果不用call,则i的最终值,输出10个10
Function.prototype.apply(thisArg[, argsArray])
在一个对象的上下文中应用另一个对象的方法;参数能够以数组形式传入。
使用apply和内置函数
聪明的apply用法允许你在某些本来需要写成遍历数组变量的任务中使用内建的函数。在接下里的例子中我们会使用Math.max/Math.min来找出一个数组中的最大/最小值。
var numbers = [5, 6, 2, 3, 7]; var max = Math.max.apply(null, numbers); var min = Math.min.apply(null, numbers);
function minOfArray(arr) { var min = Infinity; var QUANTUM = 32768; for (var i = 0, len = arr.length; i < len; i += QUANTUM) { var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len))); min = Math.min(submin, min); } return min; } var min = minOfArray([5, 6, 2, 3, 7]);
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])
bind()方法会创建一个新函数(新函数与被调函数具有相同的函数体)称为绑定函数。
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.add = function() { return this.x + this.y; }; var p = new Point(1, 2); console.log(p); //Point { x: 1, y: 2 } var YAxisPoint = Point.bind({}, 5); var x = new YAxisPoint(6); console.log(x); //Point { x: 5, y: 6 } console.log(x.add()); //11
bind() 最简单的用法是为原函数创建一个绑定函数,绑定到指定的对象上,使这个函数不论怎么调用都有同样的 this 值
this.x = 9; var module = { x: 81, getX: function() { return this.x; } }; module.getX(); // 返回 81 var retrieveX = module.getX; retrieveX(); // 返回 9, 在这种情况下,"this"指向全部作用域 // 创建一个新函数,将"this"绑定到module对象 // 新手可能会被全局的x变量和module里的属性x所迷惑 var boundGetX = retrieveX.bind(module); boundGetX(); // 返回 81
bind()的另一个最简单的用法是使一个函数拥有预设的初始参数
function list() { return Array.prototype.slice.call(arguments); } var list1 = list(1, 2, 3); // [1, 2, 3] var leadingThirtysevenList = list.bind(undefined, 37); var list2 = leadingThirtysevenList(); // [37] var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
function foo(x,y){ return y ? x+y : foo.bind(void 0,x) } console.log(foo(1,4)); //3 console.log(foo(1)(4)); //3
配合 setTimeout,在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window (或全局)对象。当使用类的方法时,需要 this 引用类的实例,你可能需要显式地把 this 绑定到回调函数以便继续使用实例。
function LateBloomer() { this.petalCount = Math.ceil(Math.random() * 12) + 1; } LateBloomer.prototype.bloom = function() { window.setTimeout(this.declare.bind(this), 1000); }; LateBloomer.prototype.declare = function() { console.log(‘I am a beautiful flower with ‘ + this.petalCount + ‘ petals!‘); }; var flower = new LateBloomer(); flower.bloom(); // 一秒钟后, 调用\‘declare\‘方法
获取函数的实现源码的字符串。覆盖了 Object.prototype.toString 方法。
原生JS:Function对象(apply、call、bind)详解
标签:
原文地址:http://www.cnblogs.com/susufufu/p/5850180.html