零基础入门-javaScript学习笔记之对象和不一样的this

在js中对象是由一系列的属性和属性的值组成的。属性的名字是字符串,而值是js的任意对象,在js中一切皆是对象,包括函数。

 

对象的声明 var a = newObject();var a = {}; 都是声明一个新对象。

而当需要定义一个具体对象的时候,可以是先声明一个空对象,然后再往里面填充属性,如

var person= {};
   person.name="jack";
   person.speak= function(){
        console.log(this.name)
    }

 

当然也可以是直接声明

var person= {
    name:"jack",
    speak:function(){
        console.log(this.name)
    }
};

person.speak();

 

这两个的效果是等价的,而在调用其属性的时候,可以用点来调用,也可以使用[]来调用,之前说过,属性名都是字符串,那么就可以person[“name”]来访问其属性。Js对属性命名没有非常严格的要求,可以在属性名中包含有点,如name.first那在这种情况之下,用点来访问其属性将会出错,使用[]来访问就不会有问题。

 

通过 “构造函数”来创建    

 

function Person(name){
    this.name= name;
    this.speak= function(){
        console.log(this.name);
    }
}
var a = new Person("jack");
a.speak();

 

以一个函数来构造一个对象,它类似于c/c++中的构造函数,不同的是需要在这个函数中构造好其属性和方法,当然也可以在对象生成之后再动态添加其属性和方法。使用函数来构造的时候一定要用new 符号,否则就是声明一个改函数的引用。

 

This 不是 this

 

Js中的this 与c/c++中的this有着非常大的差别,在c/c++中,因为属性与方法都是直接定义在类中,此时this始终指向的是这个类的实例。而在js中,对象的方法是可以外部定义的。那么this 就不一定指向对象自身了。

 

一个常见的误解就是this指向自己。

function speak(){
    var myName='jack';
    console.log(this.myName);
}
speak();

 

>>undefined

 

在函数speak 中定义了myname这个属性,但是在输出的时候却没有和预期一样的输出,这是为何。其原因是在执行speak时,this并不指向speak这个函数,可以说this始终不会指向一个函数。This 与函数调用时候的上下文有关。上下文是什么?在刚开始学习js的时候,上下文似乎是一个非常玄乎的东西,书中也没有明确的定义其含义。为了了解其含义,再来看一个例子

function speak(){
    console.log(this.myName);
}

var person={
    myName:'jack',
    speak:speak
}
var talk = person.speak;
talk();
person.speak();

 

>>undefined

>>jack

 

两个相同的函数却输出了不同的结果,这在我刚开始接触js的时候也非常的诧异。而其本质原因就联系着所谓的上下文。在第一个talk 中,其本质只是对函数speak 的一个引用。调用talk()和调用speak()本质是一样的。因为当前上下文并不是person对象,所以this指向的不是person对象,故不会有正确的输出。而当函数以对象名.函数名的形式来访问的时候,当前上下文就会变成该对象,此时this指向该对象。所以person.speak()可以正确输出。

 

让我们在来看一个例子:

 

function talk(){
    console.log(this.myName);
}
function speak(){
    console.log(this);
  talk();
}

var person={
    myName:'jack',
    speak:speak
}

person.speak();

 

>>{ myName: 'jack', speak: [Function:speak] }

>>undefined

 

在这段代码中,我们以person.speak()形式来调用speak方法,将speak 函数的上下文设为person。企图在speak中通过调用talk函数来输出。不过结果却是不如人意。这是因为在speak方法中,this 确实已经指向person对象,但是在调用talk的时候,并不是以对象.方法名的形式来掉用,所以talk 函数中,this指向的不是person对象。让我们回到最初的问题来看看。

 

 function speak(){
    var myName='jack';
    console.log(this.myName);
}  

 

speak()函数因为上下文并不是函数自己,故在此this 不是指向函数本身。在此this应该是指向一个全局对象。因为在函数定义的时候,其本质就是在全局对象中定义一个方法。它可能是类似于 global.fun,故在直接调用时,this总会出错。

 

Call 和apply

 

我们已经知道了this和上下文有关,而和函数调用位置声明无关。那么不可能每次调用都是以对象.方法名的方式来调用。Js为我们提供了两个方法来改变函数的上下文,从而达到修改函数内部的this。


function speak(){
    console.log(this.myName);
}

var person={
    myName:'jack'
}

speak.apply(person);

>>jack

 

可以看到已经成功修改函数的上下文文为person,此时this为person ,函数可以正确的输出。

Call 和apply的第一个参数都为要设置的上下文。而apply的第二个参数为要调用的函数的参数,它是参数组成的数组,而call 在跟若干个参数的时候,参数之间用逗号隔开就可以。

function speak(text){
    console.log(this.myName+text);
}

var person={
    myName:'jack'
}
speak.call(person," hello");
speak.apply(person,[" hello"]);

 

>>jack hello

>>jack hello

你可能感兴趣的:(js)