Javascript -- 精通Function

344 阅读4分钟

Function 构造函数 创建一个新的Function对象。 在 JavaScript 中, 每个函数实际上都是一个Function对象。
new Function ([arg1[, arg2[, ...argN]],] functionBody)

一些属性

function.arguments : 属性代表传入函数的实参,它是一个类数组对象。

函数递归调用的时候(在某一刻同一个函数运行了多次,也就是有多套实参),那么 arguments 属性的值是最近一次该函数调用时传入的实参。

如果函数不在执行期间,那么该函数的 arguments 属性的值是 null。

arguments.callee指向函数本身

function.caller : 返回调用指定函数的函数。

如果一个函数f是在全局作用域内被调用的,则f.caller为null,相反,如果一个函数是在另外一个函数作用域内被调用的,则f.caller指向调用它的那个函数.

该属性的常用形式arguments.callee.caller替代了被废弃的 arguments.caller.

检测一个函数的caller属性的值:

function myFunc() {
   if (myFunc.caller == null) {
      return ("该函数在全局作用域内被调用!");
   } else
      return ("调用我的是函数是" + myFunc.caller);
}

function.displayName : 属性获取函数的显示名称

当一个函数的displayName属性被定义,displayName属性将返回函数的显示名称。

function doSomething() {}
console.log(doSomething.displayName); // "undefined"

var popup = function(content) { console.log(content); };
popup.displayName = 'Show Popup';
console.log(popup.displayName); // "Show Popup"

var object = {
// anonymous
  someMethod: function(value) {
    arguments.callee.displayName = 'someMethod (' + value + ')';
  }
};

console.log(object.someMethod.displayName); // "undefined"

object.someMethod('123')
console.log(object.someMethod.displayName); // "someMethod (123)"

Function.length : 属性指明函数的形参个数,记住几个特殊的例子就可以了。

console.log(Function.length); /* 1 */
console.log((function()        {}).length); /* 0 */

console.log((function(...args) {}).length); 

console.log((function(a, b = 1, c) {}).length);
// 1, only parameters before the first one with 
// a default value is counted

console.log((function(a = 1, b, c) {}).length) // 0
console.log((function(b, a = 1, c) {}).length) // 1
console.log((function(b, c, a = 1) {}).length) // 2

Function.name : 属性返回一个函数声明的名称。writable等于false。

var f = function() {};
var object = {
  someMethod: function() {}
};

console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"

var object = {
  someMethod: function object_someMethod() {}
};

console.log(object.someMethod.name); // "object_someMethod"

修改函数里this的值

call : 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。
fun.call(thisArg, arg1, arg2, ...)

apply : 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
func.apply(thisArg, [argsArray])

argsArray,从ECMAScript 5 开始可以使用类数组对象。就是说只要有一个 length 属性和(0..length-1)范围的整数属性。

var numbers = [5, 6, 2, 3, 7];

var max = Math.max.apply(null, numbers);

console.log(max);
// expected output: 7

var min = Math.min.apply(null, numbers);

console.log(min);
// expected output: 2  

使用 apply, 你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。

我们可以使用push将元素追加到数组中。并且,因为push接受可变数量的参数,我们也可以一次推送多个元素。但是,如果我们传递一个数组来推送,它实际上会将该数组作为单个元素添加,而不是单独添加元素,因此我们最终得到一个数组内的数组。

var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]  

如果用上面的方式调用apply,会有超出JavaScript引擎的参数长度限制的风险。当你对一个方法传入非常多的参数(比如一万个)时,就非常有可能会导致越界问题, 这个临界值是根据不同的 JavaScript 引擎而定的(JavaScript 核心中已经做了硬编码 参数个数限制在65536),因为这个限制(实际上也是任何用到超大栈空间的行为的自然表现)是未指定的。

bind : 方法创建一个新的函数, 当这个新函数被调用时其this置为提供的值,其参数列表前几项置为创建时指定的参数序列。

fun.bind(thisArg[, arg1[, arg2[, ...]]])

bind()的另一个最简单的用法是使一个函数拥有预设的初始参数。这些参数(如果有的话)作为bind()的第二个参数跟在this(或其他对象)后面,之后它们会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们的后面。

function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);

var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

返回函数字符串

toString : 方法返回一个表示当前函数源代码的字符串。