一、函数定义
1、函数声明
function add(i,j){ return i+j; }
特点:1、函数声明定义函数会被前置。要知道在js代码执行时,会有一个预解析,预解析时会把变量声明、函数声明提前。2、函数声明重复定义时会以最后一次定义来执行,即后面会覆盖前面的函数声明。
2、函数表达式
var add = function(i,j){ return i+j; }
3、函数实例化
var add = new Function("i","j","return (i+j)");
很少使用,不推荐
特点:1、函数实例化定义函数只能访问本地作用域和全局作用域
二、函数调用及区别
1、函数调用模式:add();
2、方法调用模式: object.add();
3、构造函数调用模式: new Function(...);
4、apply(call)调用模式:apply(call)是构造函数原型上的方法.其实现的就是函数借用的功能
例子:
function Point(x,y){ this.x = x; this.y = y; } //定义一个point构造函数 point.prototype.move(x.y){ this.x + = x; this.y + = y; } var p = new Point(0,0); //实例化一个p点 p.move(2,2); var circle = (x:1, y:1, r:1); //定义一个全局circle对象,但是circle没有move方法,所以可以用apply或者call来借用p有的move方法。 p.move.apply(circle, [2,1]);
5、各种函数调用模式的区别-this
js执行时,js引擎会在函数的本地作用域上添加this、arguments这两个临时变量。不同调用模式的区别就表现在this的指向上。
- 函数调用模式下,this指向为全局对象window
- 方法调用模式下,this指向为调用者
- 构造函数模式下,this指向被构造的对象,如果构造了多个对象,this就指向这些被构造的对象
- apply(call)调用模式下,this指向第一个参数
思考题:
var myNumber = { value: 1, add: function(i){ var helper = function(i){ console.log(this); this.value +=1; } helper(i); } } myNumber.add(1); //1、helper函数中的this指向哪个对象,2、这段代码能否实现正确逻辑 3、可以怎么修改来实现正确逻辑
三、函数传参
1、按值传递:原始类型
2、按共享传递:对象类型
var count = {a:1,b:1}; var addOne = function(obj){ obj.a +=1; obj.b +=1; return obj; } var ret = addOne(count); console.log(ret); console.log(count); //Object {a: 2, b: 2} Object {a: 2, b: 2}
但是现在还不能判定时按引用传递,因为如果是引用传递在函数内部对外部变量引用的修改,任何改变都会发生在外部变量上,实践结果如下:
var count = {a:1,b:1}; var addOne = function(obj){ obj = {a:2,b:2}; return obj; } var ret = addOne(count); console.log(ret); console.log(count); Object {a: 2, b: 2} Object {a: 1, b: 1}