javascript中的this探究

对this我想作为前端来说接触的是很多的,可能只限于能用的层次,就很多面试题来说,要完全弄懂还是有点距离的,那么我们就来加强理解下吧,参考高三和语言精粹。

this和arguments是作为函数的两个特殊对象的,参数this在面向对象编程中非常重要,它的值取决于调用的模式,在js中一共有4种调用模式,

1,方法调用模式

当一个函数保存为一个对象的属性时,我们称之为一个方法,当这个方法被调用的时候,this就被绑定到该对象,

var o = {

        val: 0,

        sayval: function(num){

            if(typeof num === ‘number‘){

                console.log(this.val + num)

            }else{

                alert(‘请输入数字‘)

            }

        }

    }

   var val = 11;

    o.sayval(1);//1

    o.sayval(2);//2

2,函数调用模式

当一个函数并非一个对象的属性时,那么它就是被当做一个函数调用的,当函数以此模式调用时,this被绑定到全局对象,

var o = {

        val: 0,

        sayval: function(num){

            if(typeof num === ‘number‘){

                console.log(this.val + num)

            }else{

                alert(‘请输入数字‘)

            }

        }

    }

    var val = 11;

    var fn = o.sayval;

    fn(1);//12

这样设计的话,当内部函数被调用的时候,this应该绑定到外部函数的this变量,但是却被绑定到了全局,这里有个解决的办法,定义一个变量并给它赋值为this,

var o = {

        val: 0,

        sayval: function(num){

            var that = this;

            var other = function() {

                if(typeof num === ‘number‘){

                    console.log(that.val + num)

                }else{

                    alert(‘请输入数字‘)

                }

            };

            other();

        }

    }

    var val = 11;

    o.sayval(1);//1 方法调用模式

这里是不是有点混了,刚开始我也有点混淆了,刚讲过,方法调用模式this会被绑定到全局,怎么这样做却是绑定到o这个对象了呢,区别在于第7行,若是将that改为this,结果就是12了,在这大胆的分析下函数执行逻辑吧,如果是this,方法调用,绑定到全局对象,this就是window.this,如果是that就不一样了,that是变量,那函数执行的时候就会根据作用域去寻找这个变量值,other函数没有就向上找,(变量作用域的知识),找到sayval里面的that,这个变量指向的this,而这里的this指的就是o这个对象。

这样给我们的启示是如果想调用这个函数的外部函数的属性,就在外部函数保存this值,再在内部函数中调用,然后再用方法调用模式去调用函数。

作为浏览器兼容性中很重要的一条:element.attachEvent绑定事件方法,当该事件触发时this指针并未绑定到element对象上,而是绑定到了window对象上,原因在于IE中事件触发时,响应函数是以一个独立函数即函数调用模式来调用的。

3,构造器模式调用

javascript 是一门基于原型继承的语言,这意味着对象可以直接从其他对象继承属性。

如果在一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将会被绑定到那个新对象上,new前缀会改变return语句的行为。

var P = function(n){

        this.name = n;

    }

    P.prototype.getName = function(){

        console.log(this.name);

    }

    var p = new P(‘jesse‘); // 这时P中的this对象呗绑定p指向的对象引用上

    p.getName();//jesse

同时new运算符还会改变函数的返回值。以函数调用模式调用P即P()返回undefined,而通过new运算符则返回一个新对象。

4,apply,call调用模式

apply方法让我们构建一个参数数组传递给调用函数。它也允许我们选择this的值,apply的方法接受两个参数,第1个是要绑定给this的值,第2个是参数数组(call的话后边是一个一个的参数)。

var add = function(a, b){

        return a + b;

    };

    var arr = [3, 4];

    var sum = add.apply(null, arr);

    console.log(sum);//7
时间: 2024-10-17 07:20:53

javascript中的this探究的相关文章

探究JavaScript中的五种事件处理程序

我们知道JavaScript与HTML之间的交互是通过事件实现的.事件最早是在IE3和Netscape Navigator 2中出现的,当时是作为分担服务器运算负载的一种手段. 通俗地理解,事件就是用户或浏览器自身执行的某种操作.而事件处理程序即为响应某个事件的函数.抽出主干,即事件处理程序为函数.  我们又把事件处理程序称为事件侦听器.  事件处理程序是以"on"开头的,因此对于事件on的时间处理程序即为onclick.时间处理程序在JavaScript中大致有五种,下面会根据这五种

JavaScript中以构造函数的方式调用函数

转自:http://www.cnblogs.com/Saints/p/6012188.html 构造器函数(Constructor functions)的定义和任何其它函数一样,我们可以使用函数声明.函数表达式或者函数构造器(见以前的随笔)等方式来构造函数对象.函数构造器和其它函数的区别在与它们的调用方式不同. 要以构造函数的方式调用函数,只需要在调用时在函数名称前加new 关键字,比如:function whatsMyContext(){ return this; }; 调用:new what

Javascript中String()与new String()的差异

这里主要关注的是值类型和引用类型. 我们知道在javascript中的变量在内存中的存储有两种形式,值类型存储和引用类型存储. 通常可以进行值存储的包括  字符串类型,布尔值类型,数字类型,他们都包含了字面量表示形式,如下: var str='str'; var bool=true; var num=11; 这里定义的变量是直接在地址中存值的,而常用的数组(其实也属于对象)和对象也有字面量,不过是引用存储,即内存中存储的是对应数据的地址(不是本文重点). 接着我们探究String()和new S

JavaScript中的事件对象

JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有关的信息.下面将会讲到DOM中的事件对象.IE中的事件对象以及跨浏览器的事件对象三个部分. 对于事件处理程序,大家可以看我的博文<JavaScript中的五种事件处理程序>. 第一部分:DOM事件对象 兼容DOM的浏览器会将一个event对象传入到事件处理程序中,无论是HMTL特性.DOM0级还是

Javascript中的继承与Prototype

之前学习js仅仅是把w3school上的基本语法看了一次而已,再后来细看书的时候,书中会出现很多很多没有听过的语法,其中一个就是js的继承以及总能看到的prototype.我主要在看的两本js书是<javascript权威指南>,也就是那本犀牛书,还有一本是疯狂xx系列的<疯HTML5/CSS3/Javascript讲义>.前者非常适合用啃js细节,如果需要深入学习一些js内部机制以及相关的内容,这本大块头啃起来还是挺有味道的.后者是本速成教材,可以让你对某个概念有一个非常舒服的打

javascript中var、let和const的区别

在javascript中,var.let和const都可以用来声明变量,那么三者有什么区别呢?要回答这个问题,我们可以从先想想:三种不同的声明会影响变量的哪些方面?这些方面也就是变量的特性,那么变量有哪些特呢?无非就是两个:一个是变量的数据类型,是数字,字符串还是数组或者其他的,另一个就是变量的作用域,是全局的还是局部的,又或者是某个代码块的.因此我们可以从以下两个方面来探究三种声明方式的区别: 1.声明后变量的数据类型有什么不同? 2.声明后变量的作用域有什么不同? 先看第一个方面,数据类型有

实现一个函数clone,使JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制. 1 /** 对象克隆 2 * 支持基本数据类型及对象 3 * 递归方法 */ 4 function clone(obj) { 5 var o; 6 switch (typeof obj) { 7 case "undefined": 8 break; 9 case "string": o = obj + &q

javascript中的原始值和复杂值

前面的话 javascript的数据类型可以分为两种:原始类型(基本类型或者简单类型)和引用类型. 原始类型:Undefined,Null,Boolean,Number,String五种: 引用类型:Object,Array,Function: 与此相对应的,它们的值分别被称为原始值和复杂值. 特性 原始值 原始值是表示javascript中可用的数据或信息的最底层的形式或者最简单的形式.原始类型的值被称为原始值,因为它们的值是不可被细化的.也就是说,数字是数字,字符串是字符串,布尔值是true

【JS】JavaScript中的执行环境与作用域

JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是作为window对象的属性和方法创建的.当某一个执行环境中所有代码执行完成后,该环境就被销毁,保存在其中的变量和函数也将被销毁,全局执行环境在关闭网页或浏览器时才被销毁. 当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的变量和函数的有序访问),如果环境是函数,将其活动