走进面向对象编程世界第一步(this&call&apply&bind)

1. firstCase

CODE
 var obj1 = {
  name:"everyone",
  hi:function(){
    console.log("Hello!" + obj1.name)
  }
}
obj1.hi()
obj1.hi.call() 
CONSOLE
"Hello!everyone"
"Hello!everyone"

2. secondCase

CODE
var obj2 = {
  name:"jack",
  hi:function(person){
    console.log("hi!" + person.name )
  }
}
obj2.hi(obj2)
//obj2.hi.call(obj2),出错
CONSOLE
"hi!jack"

3. thirdCase

CODE
var obj3 = {
  name:"rose",
  hi:function(name){
    console.log("hi!" + 
  name)
  }
}
obj3.hi(obj3.name)
obj3.hi.call(obj3.name)
CONSOLE
"hi!rose"
"hi!undefined"
COMMENT
  • call传入的参数不能使对象的属性

4. fourthCase

CODE
var obj4 = {
  name:"lucy",
  hi:function(object,问候语){
    console.log(问候语 + '!我是' + object.name )
  }
}
obj4.hi(obj4,'你好')
obj4.hi.call(obj4,'你好')
CONSOLE
"你好!我是lucy"
"undefined!我是undefined"
COMMENT
  • 函数接收的对象由this接收,不能直接在函数形参上调用

5. fifthCase

CODE
var obj5 = {
  name:"萝莉",
  hi:function(问候语){
    console.log(问候语 + this.name)
  }
}
obj5.hi('最近过得如何?')
obj5.hi.call(obj5,'最近过得如何?')
obj5.hi.apply(obj5,['最近过得如何?'])
CONSOLE
"最近过得如何?萝莉"
"最近过得如何?萝莉"
"最近过得如何?萝莉"
COMMENT
  • 函数调用,可以通过call传参数,也可以通过apply传参
  • call传的是字符串,apply传的是数组
  • 函数的this有call传入对象,通过this[属性],去取对象上的属性值

6. sixthCase

CODE
var obj6 = {
  hi:function(){
    console.log(this)
  }
}
var HI = obj6.hi
HI()
obj6.hi()
CONSOLE
Window
obj6
COMMENT
  • this值取决于函数调用时的环境
  • 当函数赋值给全局变量时,this指向Window
  • 当函数赋值给对象的属性时,this指向调用的对象obj6

7. seventhCase

CODE
var obj7 = {
  hi:function(p1){
    console.log(this);
    console.log(typeof this);
    console.log(typeof 11);
    console.log(p1)
  }
}
var HI = obj7.hi
HI.call(22,"hello")
CONSOLE
22
"object"
"number"
"hello"

8. eighthCase

CODE
var fn = function(){
  console.log(this)
}
var obj8_1 = {
  hi:fn
}
var obj8_2 = {
  hi:fn
}
fn()
fn(11)
fn.call({name:"lin"})
obj8_1.hi()
obj8_2.hi()
CONSOLE
Window
Window
{name:"lin"}
obj8_1
obj8_2
COMMENT
  • 直接调用函数,this指向Window
  • 传入参数是对象,则this指向参数对象
  • 以对象的属性调用函数,则this指向对象

9. ninthCase

HTML

JavaScript
xxx.onclick = function(e){
  console.log(this)
}
CONSOLE
[object HTMLButtonElement]

COMMENT
  • 点击xxx按钮时,触发click事件的target元素对象
  • this指向target元素对象

10. tenthCase

JavaScript
setTimeout(function(){
  console.log(this)
},1000)
CONSOLE
Window

11. eleventhCase

JavaScript
var obj11 = {
  hi:function(){
    console.log(this)
  }
}
setTimeout(obj11.hi,1000)
setTimeout(obj11.hi.bind(obj11),1000)
CONSOLE
Window
obj11
COMMENT
  • 定时器,是由浏览器控制的,调用的对象是Window
  • bind()创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列

12. twelfthCase

JavaScript
function fn(){
  console.log(this)
}
fn.bind({name:"qing"}).call({name:"li"})
CONSOLE
{name:"qing"}

13. thirteenthCase

JavaScript
function fn(){
  console.log(this)
}
fn.bind({name:"qing"}).call({name:"li"})
CONSOLE
{name:"qing"}

14. fourteenthCase

JavaScritpt
var a = [1,2,3]
var b ={0:4,1:5,2:6,length:3}

console.log(a.slice.call(b,0,2))
CONSOLE
[4, 5]

15. fifteenthCase

HTML

JavaScript
var name = 'wang'
var obj14 = {
  name:'lin',
  listen:function(){
    console.log("obj14:"+this);
    console.log('name:'+this.name)
    xxx.onclick = function(){
      console.log("onclick.this:" + this)
    }
  }
}
obj14.listen()
CONSOLE
"obj14:[object Object]"
"name:lin"
"onclick.this:[object HTMLButtonElement]"
COMMENT
  • 第一个this指向函数所在属性的对象
  • 第二个this指向触发click事件的''元素对象
补充ES6新语法中的this

箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,
而不是指向运行时所在的作用域

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000);
  // 普通函数
  setInterval(function () {
    this.s2++;
  }, 1000);
}

var timer = new Timer();

setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0

第一个this指向构造函数Timer的实例
第二个this指向window

你可能感兴趣的:(走进面向对象编程世界第一步(this&call&apply&bind))