这部分比较简单,直接看代码吧:javascript
function hello() { console.log('Hello, World'); } // 函数的调用 hello(); // Hello, World var obj = { welcome: function() { console.log('Hello, ' + this.name); }, name: 'dreamapple' }; // 方法调用 obj.welcome(); // Hello, dreamapple function Student(name, age) { this.name = name; this.age = age; console.log('My name is ' + this.name + ', and my age is ' + this.age); } // 构造函数的调用 var s = new Student('dreamapple', 23); // My name is dreamapple, and my age is 23
注意 :java
函数调用将全局对象(处于严格模式下则为undefined)做为接收者。通常不多使用函数调用语法来调用方法。数组
方法调用将被查找方法属性的对象做为调用接受者。闭包
构造函数须要经过new运算符调用,并产生一个新的对象做为其接受者。app
JavaScript中将函数做为参数或返回值的函数被称为高阶函数,下面介绍一些经常使用的JS内置高阶函数函数
sort
函数须要使用者传入一个排序规则,以下:this
var arr = [1, 9, 3, 4, 2]; // 返回一个排序的结果 var arr1 = arr.sort(function(x, y) {return x>y?1:-1}); console.log(arr1); // [ 1, 2, 3, 4, 9 ]
使用 map
能够简化对数组的遍历操做,其参数为一个函数,以下:code
var arr = [1, 9, 3, 4, 2]; var arr2 = arr.map(function(x) { return x * 2 + 1; }); console.log(arr2); // [ 3, 5, 7, 9, 19 ] var arr3 = [1.4,1.5,3.2,3.6] arr3 = arr3.map(Math.ceil) console.log(arr3)//[2, 2, 4, 4]
使用call方法自定义接受者来调用函数。对象
使用call方法能够调用在给定的对象中不存在的方法。排序
使用call方法定义高阶函数容许使用者给回掉函数指定接收者。
// 使用call var obj1 = { sayHello: function(msg) { console.log('Hello,' + this.name + ' ' + msg); }, name: 'dreamapple' }; var obj2 = { name: 'dream' }; // 第一个参数是方法的调用者,剩余的参数就是原函数的参数 obj1.sayHello.call(obj2, 'haha'); // Hello,dream haha // 高阶函数使用call function compute(arg) { var sum = 0; for(var i = 0; i < arg.length; i++) { sum += arg[i]; } return sum; } function highFunc() { return compute.call(null, arguments); } console.log(highFunc(1, 2, 3, 4, 5)); // 15 var arr = [1,2,3,4,5]; console.log(highFunc(arr)); // 错误
JavaScript给每一个函数都隐式地提供了一个局部变量 arguments
使用隐式的arguments对象实现可变参数的函数。
考虑对可变参数的函数提供一个额外的固定元数的版本,从而使使用者无需借助apply方法。
// 多参数函数 function multArgsFunc() { console.log(arguments); //[1, 2, 3, 4, 5] var sum = 0; for(var i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; } console.log(multArgsFunc(1, 2, 3, 4)); // 10 console.log(multArgsFunc(1, 2, 3, 4, 5)); // 15
注意:
永远不要直接修改arguments对象
arguments
是一个对象,不是数组,能够经过 [].slice.call(arguments)
将其复制到一个真正的数组中再进行操做
当使用 arguments
时小心函数嵌套,一般应该使用变量保存 arguments
的引用
使用apply方法指定一个可计算的的参数数组来调用可变参数的函数。
使用apply方法的第一个参数给可变参数的的方法提供一个接收者。
注意:
apply的用法和call相似,惟一的区别在于call不接受参数数组,而apply能够接受参数数组,即便参数个数固定只有一个或两个,使用apply时也须要将参数用 []
包裹起来,例子以下:
// 使用apply function compute() { var sum = 0; for(var i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; } function wrapper(arr) { return compute.apply(null, arr); // 给compute函数传递多个参数 } var arr = [1, 2, 3, 4, 5]; console.log(wrapper(arr)); // 15
使用 bind
来提取具备肯定接受者的方法
要注意, 提取一个方法不会将方法的接受者绑定到该方法的对象上。
当给高阶函数传递对象方法时,使用匿名函数在适当的接受者上调用该方法。
使用bind方法建立绑定到适当接收者的函数。
调用 f.bind(someObject)
会产生一个新的函数对象。在这个新的函数对象中,this被永久绑定到了bind的第一个参数上面,不管后期这个新的函数被如何使用。
示例以下:
function f(){ return this.a; } var g = f.bind({a:"jack"}); console.log(g()); // jack var o = {a:37, f:f, g:g}; console.log(o.f(), o.g()); // 37, jack function Person(name){ this.nickname = name; this.distractedGreeting = function() { setTimeout(function(){ console.log("Hello, my name is " + this.nickname); }, 500); } } var alice = new Person('Alice'); alice.distractedGreeting(); //Hello, my name is undefined function Person(name){ this.nickname = name; this.distractedGreeting = function() { setTimeout(function(){ console.log("Hello, my name is " + this.nickname); }.bind(this), 500); // <-- this line! } } var alice = new Person('Alice'); alice.distractedGreeting(); // after 500ms logs "Hello, my name is Alice" this.x = 9; var module = { x: 81, getX: function() { return this.x; } }; module.getX(); // 81 var getX = module.getX; getX(); // 9, 由于在这个例子中,"this"指向全局对象 // 建立一个'this'绑定到module的函数 var boundGetX = getX.bind(module); boundGetX(); // 81
当调用函数的toString方法时,并无要求JavaScript引擎可以精确地获取到函数的源代码。
因为在不一样的引擎下调用toString方法的结果可能不一样,因此绝对不要信赖函数源代码的详细细节。
toString方法的执行结果并不会暴露存储在闭包中的局部变量值。
一般状况下,应该避免使用函数对象的toString方法。
(function(x) { return x + 1; }).toString(); /* * 输出结果 * function (x) { * return x + 1; * } * */ (function(x) { return x + 1; }).bind(10).toString(); /* * 因为使用了宿主环境的内置库提供的函数,JavaScript引擎会视图提供该函数的源代码的真实表示 * 而宿主环境中bind一般是其余语言(如C++)提供的是一个编译后的函数 * function (x) { [native code] } * */ (function(x) { return function(y) { return x + y; } }).bind(20).toString(); /* * function () { [native code] } * */