一、函数调用模式
function add1(i){
console.log("函数声明:"+(i+1));
}
add1(1);
二、方法调用模式
var myNumber = {
value: 1,
add: function(i){
console.log(this);
this.value += i;
}
}
myNumber.add(1);
三、构造函数调用模式
(构造函数:首字母大写)
// 定义一个构造函数
var Person = function() {
this.name = "程序员";
this.sayHello = function() {
alert("你好,这里是" + this.name);
};
};
// 调用构造器,创建对象
var p = new Person();
// 使用对象
p.sayHello();
四、apply(call)调用模式
apply:Function构造函数原型对象上的一个方法
构造函数上的属性可以构造函数原型链上的函数所引用。
构造函数有一个prototype属性,prototype属性,有一个apply方法。
prototype:返回对象类型原型的引用。
任何function函数都是Function构造函数的实例
function Point(x,y){
this.x=x;
this.y=y;
}
Point.prototype.move=function{
this.x+=x;
this.y+=y;
} //在Point构造函数的原型对象上创建一个move方法
var p=new Point(0,0)//实例化的p函数可以访问move方法
var circle={x:1,y:1,r:1}
p.move.apply(circle,[2,1])//circle对象调用move函数
四种调用模式的区别
JS引擎会在调用函数时会在本地作用域上自动生成两个变量,this和arguments。调用方法的不同就体现呢在this指向的不同。
函数调用模式:
this 指向全局作用域
function add(i,j){
console.log(this);
(function(){
console.log(this);
})()
}
add();
两次执行结果,this都是window全局作用域
Window {external: Object, chrome: Object, document: document, io: Object, puer: Object…}
Window {external: Object, chrome: Object, document: document, io: Object, puer: Object…}
方法调用模式:
this:执行方法的调用者
var myNumber = {
value: 1,
add: function(i){
console.log(this);
this.value += i;
}
}
myNumber.add(1);//Object {value: 1}
深入理解this,思考下面的问题:
1.以下代码中打印的this是个什么对象?
2.这段代码能否实现使myNumber.value加1的功能?
3.在不放弃helper函数的前提下,有哪些修改方法可以实现正确的功能?
var myNumber = {
value: 1,
add: function(i){
var helper =function(i){
this.value+= i;
}
helper(i);
}
}
myNumber.add(1);
构造函数调用:
this指向被构造的对象
apply(call)调用模式:
this指向apply的第一个参数
函数调用生成的另一个参数: arguments
类似数组的对象array-like
-arguments[index]
-arguments.length
函数传参:
原始类型:按值传递
对象类型:按共享传递
参数传递的几种类型:
1、按值传递call by value
外部变量传递给函数时,函数形参获取的是外部变量的副本,当在函数内修改外部变量时,外部变量不会发生变化。
var count = 1;
var addOne = function(num) {
num += 1;
return num;
}
var ret = addOne(count);
console.log(ret);//2
console.log(count);//1
2、按引用传递 call by reference
外部变量传递给函数时,函数形参是外部变量的一个引用,在函数内部对函数的任何修改,会反馈到外部变量。
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);//Object {a: 2, b: 2}
console.log(count);//Object {a: 2, b: 2}
(实际是按共享传递的。在函数内部,函数改变了堆内存中的值,即改变了count和obj的指向的值)
3、按共享传递 call by sharing
外部变量传递给函数时,形参obj获取的是count地址的一个副本。(count是对象类型数据,count指针(位置)存放在栈内存中,数据存放在堆内存虫。)此时obj和count指向的是同一个对象({a:1,b:1}),这个对象值得变化会同时反应在obj和count上。
在函数内部,把obj指向了另一个对象({a:2,b:2}),不影响count指向的对象。
var count = {a:1,b:1};
var addOne = function(obj) {
obj = {a:2, b:2};
return obj;
}
var ret = addOne(count);
console.log(ret);//Object {a: 2, b: 2}
console.log(count);//Object {a:1,b:1}