03月06, 2018

JavaScript 的 Function

使用Function构造器生成的Function对象是在函数创建时解析的。这比你使用函数声明或者函数表达式(function)并在你的代码中调用更为低效,因为使用后者创建的函数是跟其他代码一起解析的。

所有被传递到构造函数中的参数,都将被视为将被创建的函数的参数,并且是相同的标示符名称和传递顺序

属性

function.arguments

以数组形式获取传入函数的所有参数。 arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数的条目,第一个条目的索引从0开始。arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性

function People() {

}

function ClassMate(name = "张三",age = 18) {
    console.log(ClassMate.arguments instanceof Array)//false
    this.name = name;
    this.age = age;
    console.log(ClassMate.arguments)//{"0":"李四","1":91}
}

new ClassMate('李四',91)

arguments对象的属性

  • arguments.callee 指向当前执行的函数。(严格模式不可用)
  • arguments.caller 指向调用当前函数的函数。
  • arguments.length 指向传递给当前函数的参数数量。
  • arguments[@@iterator] 返回一个新的Array迭代器对象,该对象包含参数中每个索引的值。

function.caller

获取调用函数的具体对象。

Function.length

获取函数的接收参数个数。

Function.name

获取函数的名称。

Function.displayName

获取函数的display name。

Function.prototype

获取函数的原型。

function People() {

}

function ClassMate(name = "张三",age = 18) {
    console.log(ClassMate.arguments)//{ '0': '李四', '1': 91 }
    console.log(ClassMate.caller)//[Function]
    console.log(ClassMate.length)//0
    console.log(ClassMate.name)//ClassMate
    console.log(ClassMate.prototype)//ClassMate {}
    console.log(ClassMate.displayName)undefined
    this.name = name;
    this.age = age;
}

new ClassMate('李四',91)

方法

Function.prototype.apply()

在一个对象的上下文中应用另一个对象的方法;参数能够以数组形式传入。

Function.prototype.bind()

bind()方法会创建一个新函数,称为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数.

Function.prototype.call()

在一个对象的上下文中应用另一个对象的方法;参数能够以列表形式传入。当call的第二个参数为数组时,会把该数组当成第一个参数,然后其他参数从数组的第二位起取。会改变方法内部的this为第一个参数对象。

function ClassMate(name = "张三",age = 18) {
    this.name = name;
    this.age = age;
    return this;
}

let obj = {
    key : "key",
    value : "value"
}
let call_1 = ClassMate.call(obj,['李四',91]);
let call_2= ClassMate.call(obj,'李四',91);
let call_3= ClassMate.apply(obj,['李四',91]);
//TypeError: CreateListFromArrayLike called on non-object
//let call_4= ClassMate.apply(obj,'李四',91);
console.log(call_1)//{ key: 'key', value: 'value', name: '李四', age: 91 }
console.log(call_2)//{ key: 'key', value: 'value', name: '李四', age: 91 }
console.log(call_3)//{ key: 'key', value: 'value', name: '李四', age: 91 }

//bing函数,返回一个函数,函数中的this,指向obj
function ClassMate(name = "张三",age = 18) {
    this.name = name;
    this.age = age;
    return this;
}

let obj = {
    key : "key",
    value : "value"
}
let bind = ClassMate.bind(obj,"李四","张三");
console.log(bind())//{ key: 'key', value: 'value', name: '李四', age: '张三' }
//这么写结果一样
let bind = ClassMate.bind(obj);
console.log(bind("李四","张三"))//{ key: 'key', value: 'value', name: '李四', age: '张三' }



function say(name = "张三",age = 18) {
    return `hello ${name} 年龄 ${age}`
}

console.log(say())//hello 张三 年龄 18
console.log(say.call(null,"李四",81))//hello 李四 年龄 81
/*
当call的第二个参数为数组时,会把该数组当成第一个参数,然后其他参数从数组的第二位起取,
比如name =["李四",81,88]
age = ["李四",81,88][1]
*/
console.log(say.call(null,["李四",81,88]))//hello 李四,81 年龄 18
console.log(say.apply(null,["李四",81]))//hello 李四 年龄 81
//console.log(say.apply(null,"李四",81))TypeError: CreateListFromArrayLike called on non-object
console.log(say.call("李四"))//hello 张三 年龄 18

Function.prototype.isGenerator()

若函数对象为generator,返回true,反之返回 false。

Function.prototype.toSource()

获取函数的实现源码的字符串。 覆盖了 Object.prototype.toSource 方法。 鸡肋,好多环境报错

Function.prototype.toString()

获取函数的实现源码的字符串。覆盖了 Object.prototype.toString 方法。

箭头函数

箭头函数也称为 lambda 表达是,java在jdk8中也引入了这个特性。

const sum = (() => 1+2)();
console.log(sum)//3

const sumFunction = (x,y) => x+y;
console.log(sumFunction)//[Function: sumFunction]

箭头函数有几个使用注意点。

  • (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

  • (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

  • (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

  • (4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

本文链接:https://www.qiangshuidiyu.xin/post/js-function.html

-- EOF --

Comments