JS面向对象之三【this】 (对象和函数之间的关系)

极客涟漪
• 阅读 2149

JS面向对象之三【this】 (对象和函数之间的关系)

上一篇,谈了对象和对象的关系,现在我们谈谈对象和函数的关系

先说结论,也就是观点1

观点1: JS里函数和对象没有关系,JS之父通过this将他们强行关联起来

首先我们根据场景,去理解this的出现可以解决什么问题。

    var obj = {
        name : 'ziwei',
        sayName: function(x){
            return console.log('hello,' + x.name)
        }
    }
   

现在我们不用this,我们就只能这样调方法
obj.sayName(obj)

但是一般而言,我们用obj调用sayName,肯定就是希望让这个对象说自己的名字

为了能够obj.sayName(),让这个obj自己的传递进去,JS之父发明了this.

this的出现,就可以解决obj.sayName(obj)时,不用自己传递obj进去,而是直接obj,sayName(),让JS会帮你传递obj参数进去

你可以理解为JS做了一件事情,就是你每次调用函数时,都偷偷给你传递了一个参数,你用this就可以拿到这个参数。

    var obj = {
        name : 'ziwei',
        sayName: function(){
            return console.log('hello,' + this.name)
        }
    }
    obj.sayName()   

但是这样,其实对于新手很不友好。我obj.sayName(),根本没传递参数,那他是怎么输出obj的name的呢?

所以JS偷偷的传递this参数这件事情,我们将它显式的展出来就好理解了。

实际上,JS就是做了这样一件事情,显式的指定this是obj. obj.sayName.call(obj)

回顾一下:

隐式模式: obj.sayName()
显示模式: obj.sayName.call(obj)

观点2: JS里所有函数都接受2个参数,第一个this,第二个是arguments

JS函数被调用时,一定会有这2个参数

如果你用call()调用函数,就是显式的传递this和arguments
如果你用()语法直接调用函数,那JS就去帮你偷偷的传递this。它怎么帮你传递呢? 这个问题暂时不管,下面会说。

JS其实为了用this,想了很多折中方案。
包括(1)函数调用有两种语法 , 把函数的参数划分为this和arguments

一个三段论
  • 论点1: JS函数的参数的值,只有在传参时才确定的
  • 论点2: this是函数的参数
  • 推论: this的值,只有在函数调用时才确定
JS偷偷帮你传递参数的规则 (也就是你使用()语法调用时)
  • 在全局作用域下调用函数,默认是window (这个是历史遗留bug),或者你也可以理解为window对象调用的函数
  • 哪个对象调用的,这个this就指向谁
  • 构造函数里this指向构造函数的实例
  • call、apply、bind都是显式的传递this了,不用多说
  • 箭头函数里没有this,如果你非要写一个this,那这个this跟外面的this一致

做几个题目

这个this是谁?
function a(){
    console.log(this)
}

答案: 不确定,this是参数,函数没有调用,怎么确定参数的?
function a(){
    'use strict'
    console.log(this)
}

a()

答案: undefined, 严格模式下, 全局作用域下this不再是window,而是undefiend

新手不会this的主要原因,是不清楚函数的另一个调用方式call(),

因为用call()就是自己传递this, 用()就是JS偷偷帮你传递this,既然是JS按照他自己的规则,偷偷给你传递的,你肯定要懵逼搞不清的

就像手动档和自动挡开车一样

点赞
收藏
评论区
推荐文章
Karen110 Karen110
3年前
一篇文章带你了解JavaScript作用域
在JavaScript中,对象和函数也是变量。在JavaScript中,作用域是你可以访问的变量、对象和函数的集合。JavaScript有函数作用域:这个作用域在函数内变化。一、本地JavaScript变量一个变量声明在JavaScript函数内部,成为函数的局部变量。局部变量有局部作用域:它们只能在函数中访问。JS://codeherecann
Wesley13 Wesley13
3年前
java中的类与对象(1)
    首先理解一下类和对象的关系,可以说:类是对象的抽象,对象是类的实例。类一个类中,通常上包含了属性和功能。属性通常用变量表达,功能通常上用函数表达。编写一个类class类名{//属性,用变量表达//功能,用函数表达}对象实例化对象的方法及含义:类名 对象名 new 
Stella981 Stella981
3年前
Python 常用的ORM框架简介
ORM概念ORM(ObjectRalationalMapping,对象关系映射)用来把对象模型表示的对象映射到基于SQL的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作实体对象的属性和方法。ORM技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据
Stella981 Stella981
3年前
JPA、Hibernate、Spring data jpa之间的关系,终于明白了
什么么是JPA?全称JavaPersistenceAPI,可以通过注解或者XML描述【对象关系表】之间的映射关系,并将实体对象持久化到数据库中。为我们提供了:1)ORM映射元数据:JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;如:@Entity、@Table、@C
Wesley13 Wesley13
3年前
JSON学习笔记(二、语法)
JSON和js关系欲学JSON先学js,那么JSON和js的关系是什么样的呢?.JSON使用JavaScript语法来描述数据对象,但是JSON仍然独立于语言和平台。.JSON语法是JavaScript语法的子集基本语法.数据在名称/值对中.数据由逗号分隔.大括号保存对象.中括号保
Stella981 Stella981
3年前
Javascript 是如何体现继承的 ?
js继承的概念js里常用的如下两种继承方式:原型链继承(对象间的继承)类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念。所以,要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现在面向对象的语言中,我们使用类来创建一个自定义对象
Wesley13 Wesley13
3年前
JS中正则表达式
正则表达式的定义js中的正则表达式使用RegExp对象表示,两种创建正则表达式对象的方法直接量定义将表达式包含在斜杠之间varpattern/js/;构造函数定义:使用RegExp()构造函数定义varpatternnewRegExp('js');
Wesley13 Wesley13
3年前
JSON 与 JS 对象的关系
很多人搞不清楚JSON和Js对象的关系,甚至连谁是谁都不清楚。简单来说:JSON是JS对象的字符串表示法,它使用文本表示一个JS对象的信息,本质是一个字符串。如varobj{a:'ni',b:'hao'};//这是一个对象,注意键名也是可以使用引号包裹的
Stella981 Stella981
3年前
JavaScript面向对象编程的15种设计模式
在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”。在JavaScript中并没有类这种概念,面向对象编程不是基于类,而是基于原型去面向对象编程,JS中的函数属于一等对象,而基于JS中闭包与弱类型等特性,在实现一些设计模式的方式上与众不同。ps:本文之讲述面向对象编程的设计模式策略,JavaScript原型的基础请参考阮一峰面向
Stella981 Stella981
3年前
Hibernate利用关联关系操纵对象
Hibernate利用关联关系操纵对象数据对象之间关联关系有一对一、一对多及多对多关联关系。在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难。本节讲解如何在Hibernate中处理这些对象之间的关联关系。本节使用到4个类,它们分别是Student(学生)、Card(学生证)、Group(班级)和Cou
Stella981 Stella981
3年前
Javascript 基础知识学习(四)
这里接着前面一篇继续!Javascript中的所有所有事物都是对象:字符串、数值、数组、函数·····每个对象都有自己的属性和方法,JS能够自定义对象:在第七点是相关面向对象的知识点。<script//直接创建对象varpeople{n