1.具名函数/匿名函数中的this指向全局对象
function test(){ this.name = "dearxiangxiao"; console.log(this) } test()2.构造函数中的this指向构造函数
function Person(){ this.name = "dearxiangxiao"; console.log(this) } var person1 = new Person();3.方法调用的时候,this指向方法所在的对象
var robot = { name:"cup", say:function(){ console.log(this) } }; robot.say();4.apply/call调用的时候,this指向apply/call方法中的第一个参数
var robot_1 = {name:'cup'} var robot_2 = {name:'bower'} function say(){ console.log(this.name) } say.call(robot_1) // 打印结果为'cup' say.call(robot_2) // 打印结果为'bower' //call继承了第一个参数对象的属性##补充 函数的apply与call方法 所有的函数都默认包含apply和call这两种方法,调用函数的apply或call方法,就相当于调用该函数。而apply和call的功能是,通过传参的方式,强制函数内的this指定某一对象。this引用的会被指向apply/call的第一个参数。
var robot_1 ={ name:"cup", say:function(){ console.log(this.name) } }; var robot_2 ={ name:"bower" }; robot1.say() //打印结果为cup robot_1.say.apply(robot_2) // 打印结果为bower //通过apply调用robot_1.say方法。方法内的this引用引用了robot_2 robot_1.say.call(robot_2) // 打印结果为bower //通过call调用robot_1.say方法。方法内的this引用引用了robot_2apply与call之间的不同之处在于两者对其他参数的传递方式。
对于apply来说,剩余的参数将通过数组来传递 call是直接按参数列表传递
function say(age, gender){console.log("My name is " + this.name + ",I'm a " + age + " years old " + gender + ".")} say.apply({name:"cup"}, [12, "boy"]) //打印结果为 My name is cup,I'm a 12 years old boy. // this.name = "cup", age = 12, gender = "boy" 作为第二个参数的数组中的元素都是函数say的参数,按顺序依次对应 say.call({name:"cup"}, 12, "boy") //打印结果为 My name is cup,I'm a 12 years old boy. // this.name = "cup", age = 12, gender = "boy" 从第二个参数起的参数都是函数say的参数,按顺序依次对应this 案例 1
var robot = { name : "cup", say : function() { console.log( "Hi, I'm " + this.name + "."); } } var fn = robot.say; //将robot.say引用的函数赋值给全局变量 fn. //相当于给全局对象定义了一个属性fn,并赋予robot.say所指代的函数. var name = "bower", //相当于给全局对象定义了一个属性name,赋值为"bower",在浏览器里,上面这行代码等价于 window.name = "bower"; fn() // 打印结果为 Hi, I'm bower. //执行函数fn(相当于调用全局对象的fn方法),执行时this引用了全局对象.所以this.name的值是"bower".一个典型的定义类的方法
function Car(x,y){ this.x = x; this.y = y; this.run = function(x_increase, y_increase){ this.x += x_increase; this.y += y_increase; } this.show = function(){ console.log("( " + this.x + "," + this.y + " )"); } } var a_car = new Car(2,4); //获得了一个坐标为(2,4)的Car对象,x为2,y为9 a_car.run(10,5); //a_car.x变成了12,a_car.y变成了9 a_car.show(); //打印结果为 ( 12,9 )当我们使用new Car(2,4)的时候,就会生成一个对象,在调用的过程中会调用所谓的构造函数。使用这种方式去自定义类,所有的成员定义都放在构造函数里,不论函数还是属性。这样做的话,每次构造一个对象,都要对所有的函数重新分配内存。
var a_car = new Car(2,4); var b_car = new Car(3,3); 上面的代码new了两次,相应的run和show被分配了两次内存。 借鉴添加链接描述