文章目录
1.Function
Function 构造函数创建一个新的 Function 对象。直接调用此构造函数可用动态创建函数,但会遭遇来自 eval 的安全问题和相对较小的性能问题。然而,与 eval 不同的是,Function 构造函数只在全局作用域中运行。
语法
new Function ([arg1[, arg2[, ...argN]],] functionBody)
使用 Function 构造器生成的 Function 对象是在函数创建时解析的。这比你使用函数声明或者函数表达式并在你的代码中调用更为低效,因为使用后者创建的函数是跟其他代码一起解析的。
示例
const adder = new Function("a", "b", "return a + b");
const adder1 = new Function("a,b", "return a + b");
// 调用函数
adder(2, 6);//8
adder(2, 6);//8
2.Function.arguments
已废弃
该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。
function.arguments 已经被废弃了, 现在推荐的做法是使用函数内部可用的 arguments 对象来访问函数的实参。
在函数递归调用的时候(在某一刻同一个函数运行了多次,也就是有多套实参),那么 arguments 属性的值是最近一次该函数调用时传入的实参,
示例
function f(n) { g(n - 1); }
function g(n) {
console.log('before: ' + g.arguments[0]);
if (n > 0) { f(n); }
console.log('after: ' + g.arguments[0]);
}
f(2);
console.log('函数退出后的 arguments 属性值:' + g.arguments);
// 输出:
// before: 1
// before: 0
// after: 0
// after: 1
// 函数退出后的 arguments 属性值:null
3.Function.caller
返回调用指定函数的函数.如果一个函数f是在全局作用域内被调用的,则f.caller为null,相反,如果一个函数是在另外一个函数作用域内被调用的,则f.caller指向调用它的那个函数.
该属性的常用形式arguments.callee.caller替代了被废弃的 arguments.caller.
function myFunc() {
if (myFunc.caller == null) {
return ("该函数在全局作用域内被调用!");
} else
return ("调用我的是函数是" + myFunc.caller);
}
function f(n) { g(n-1) }
function g(n) { if(n>0) f(n); else stop() }
f(2)
//调用栈:
f(2) -> g(1) -> f(1) -> g(0) -> stop()
stop.caller === g && f.caller === g && g.caller === f
4.Function.length
length 属性指明函数的形参个数。 arguments.length 是函数被调用时实际传参的个数。
Function 构造器本身也是个Function。他的 length 属性值为 1 。
Function.prototype 对象的 length 属性值为 0 。
示例
console.log(Function.length); /* 1 */
console.log((function() {}).length); /* 0 */
console.log((function(a) {}).length); /* 1 */
console.log((function(a, b) {}).length); /* 2 etc. */
console.log((function(...args) {}).length);
// 0, rest parameter is not counted
console.log((function(a, b = 1, c) {}).length);
// 1, only parameters before the first one with
// a default value is counted
5.Function.name
function.name 属性返回函数实例的名称。你不能更改函数的名称,此属性是只读的。要更改它,可以使用Object.defineProperty()。
Object.defineProperty(Foo, 'name', { writable: true });
示例
function doSomething() { }
doSomething.name; // "doSomething"
构造函数的名称
(new Function).name; // "anonymous"
绑定函数的名称
function foo() {};
foo.bind({}).name; // "bound foo"
getters 和 setters 的函数名
var o = {
get foo(){},
set foo(x){}
};
var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
descriptor.get.name; // "get foo"
descriptor.set.name; // "set foo";
类中的函数名称
function Foo() {} // ES2015 Syntax: class Foo {}
var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs "Foo"
6.Function.prototype
Function.prototype 属性存储了 Function 的原型对象。Function对象继承自 Function.prototype 属性。Function.prototype 不能被修改。
//属性
Function.arguments
Function.arity
Function.caller //返回调用指定函数的函数
Function.length
Function.name
Function.displayName
Function.prototype.constructor
//方法
Function.prototype.apply()
Function.prototype.bind()
Function.prototype.call()
Function.prototype.isGenerator() //若函数对象为generator,返回true,反之返回 false。
Function.prototype.toSource() //获取函数的实现源码的字符串。
Function.prototype.toString()
7.Function.prototype.apply()
apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
语法
//thisArg,在 func 函数运行时使用的 this 值,指定为 null 或 undefined 时会自动替换为指向全局对象
//argsArray,一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。
//返回值是调用有指定this值和参数的函数的结果。
func.apply(thisArg, [argsArray])
示例
var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]
8.Function.prototype.call()
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
语法
fun.call(thisArg, arg1, arg2, ...)
返回值
使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined。
function greet() {
var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
console.log(reply);
}
var obj = {
animal: 'cats', sleepDuration: '12 and 16 hours'
};
greet.call(obj); // cats typically sleep between 12 and 16 hours
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
var cheese = new Food('feta', 5);
var sData = 'Wisen';
function display() {
console.log('sData value is %s ', this.sData);
}
//如果没有传递第一个参数,this 的值将会被绑定为全局对象。
display.call(); // sData value is Wisen
9.Function.prototype.bind()
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
语法
function.bind(thisArg[,arg1[,arg2[, ...]]])
参数
thisArg
调用绑定函数时作为this参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用bind在setTimeout中创建一个函数(作为回调提供)时,作为thisArg传递的任何原始值都将转换为object。如果bind函数的参数列表为空,执行作用域的this将被视为新函数的thisArg。
arg1, arg2, …
当目标函数被调用时,预先添加到绑定函数的参数列表中的参数。
返回值
返回一个原函数的拷贝,并拥有指定的this值和初始参数。
示例
this.x = 9; // 在浏览器中,this指向全局的 "window" 对象
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX();
// 返回9 - 因为函数是在全局作用域中调用的
// 创建一个新函数,把 'this' 绑定到 module 对象
// 新手可能会将全局变量 x 与 module 的属性 x 混淆
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
bind()的另一个最简单的用法是使一个函数拥有预设的初始参数。
当绑定函数被调用时,初始参数会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面。
function list() {
return Array.prototype.slice.call(arguments);
}
function addArguments(arg1, arg2) {
return arg1 + arg2
}
var list1 = list(1, 2, 3); // [1, 2, 3]
var result1 = addArguments(1, 2); // 3
// 创建一个函数,它拥有预设参数列表。
var leadingThirtysevenList = list.bind(null, 37);
// 创建一个函数,它拥有预设的第一个参数
var addThirtySeven = addArguments.bind(null, 37);
var list2 = leadingThirtysevenList();
// [37]
var list3 = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]
var result2 = addThirtySeven(5);
// 37 + 5 = 42
var result3 = addThirtySeven(5, 10);
// 37 + 5 = 42 ,第二个参数被忽略
在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window (或global)对象
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// 在 1 秒钟后声明 bloom
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'方法
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.apply.bind(unboundSlice);
// ...
slice(arguments);
10.Function.prototype.toString()
Function对象覆盖了从Object继承来的toString 方法。对于用户定义的 Function 对象,toString方法返回一个字符串,其中包含用于定义函数的源文本段。
function sum(a, b) {
return a + b;
}
console.log(sum.toString());
// expected output: "function sum(a, b) {
// return a + b;
// }"