JavaScript基础 this

this

函数里面都能this, this指向是由函数执行的方式来决定的

一、函数自执行this指向window;

function a(){
      alert( this ); //弹出window
}
a();

二、无论哪种形式的事件函数,函数内部this指向都是触发事件的对象;

document.onclick = a; ===>弹出document

冒泡里的this

<div id='box'></div>
var oBox = document.getElementById ( 'box' );
oBox.onclick = a;      //这里点击box的时候也会点击document  所以会弹出2次;
document.onclick = a;    div    document

特殊情况:

一、
var a = function (){
    console.log( this ); ====>指向window;
};
a();

二、
var a = function (){
    console.log( this ); ====>指向window;
};
function b(){
  a();
}
b();  

自执行的this都是指向window

三、对象.属性(有函数) 函数内部this指向该函数

var oBox = document.getElementById ( 'box' );
oBox.a = function (){ //给对象属性加函数
    console.log(this); //指向对象本身;
}
oBox.a(); <===>  (oBox.a)();

document.onclick = oBox.a; 指向document

改变this指向

call方法
1、在函数执行阶段使用,可以改变this指向;
2、.call(第一参数,实参,实参,....) 第一个参数是改变this,后面的要传的实参
3、都用 , 隔开

1、没有传参的时候

var oBox = document.getElementById( 'box' );
function a(){
    console.log( this );
}
a(); //这里指向window;
现在要把this改为document
a.call(document); //打印document
a.call( oBox );//打印出box;

2、有传参的时候

function a( x , y ){
    console.log( x );
    console.log( y );
    console.log( this );
}
a( 200 , 200 ) //这里this指向window
a.call( document , 200 , 200 ) //这里this指向document

3、有多个形参的时候

.call(改变this , x , y , z , i,......);// x y z i ...对应的上面形参

4、其他数据类型this指向

function x( x ){
    console.log( this );
}
x( 0 ); //这里指向Number;
x( 10 ); //这里指向Number;

x( '你好' ); //这里指向String;
x( true );//这里指向Boolean;
x( [] );//这里指向数组;

x( null )//这里指向window
x( undefined )//这里指向window

null和undefined里都是指向window

apply方法
1、在函数执行阶段使用,可以改变this指向
2、apply的第一个参数代表函数 this 指向
3、apply的第二个参数是一个数组,数组的第一位对应原函数的第一个形参,以此类推;

1没有传参的时候

function a(){
      console.log( this );
}
a(); //指向window
a.apply( document )//指向document
a.apply( oBox )//指向oBox

有传参的时候

function a( x , y ){
      console.log( this );
}
a.apply( document , [ 10 , 20 ])//第一个改变this  第二是数组    数组里的第一位是对应的第一个形参   第二位对应第二形参   以此类推;
  这里this = document  x = 10 ; y = 20 ;

4、其他数据类型this指向
apply和call一样,第一个参数unll 、undefined时,this都是指向window

对象属性函数里的this

var oBox = document.getElementById( 'box' );
oBox.a = function (){
    console.log( this );
}
oBox.a(); ==>这里指向oBox

改变this的指向

oBox.a.call( document ) ==>指向document
oBox.a.call( Math ) ==>指向Math  数学对象

案例

<style>
    div{
        width: 200px;
        height: 200px;
        background: #000;
        transition: all 0.5s;
    }
    div#wrap{
        background: red;
    }
</style>
<body>
    <div id='box'></div>
    <div id="wrap"></div>
    <script>
        var oBox = document.getElementById( 'box' );
        var oWrap = document.getElementById( 'wrap' );

        oBox.onclick = function (){
            this.style.width = '400px';
            this.style.height = '400px';
        }
        oWrap.onclick = function (){
            this.style.width = '400px';
            this.style.height = '400px';
        }

====可以写成
      oBox.onclick = fn;
      oWrap.onclick = fn;

      function fn(){
          this.style.width = '400px';
          this.style.height = '400px';
      }
====我们要利用传参来改变宽高 这样扩展性好
      function fn( x , y ){
          console.log( this );
          this.style.width = x + 'px';
          this.style.height = y + 'px';
      }
      oBox.onclick = fn( 400 , 400 );  //这里不能这写,加上括号函数马上会自执行===>这里this指向window
      oWrap.onclick = fn;

====改写成
      function fn( x , y ){
          console.log( this );
          this.style.width = x + 'px';
          this.style.height = y + 'px';
      }
      oBox.onclick = function (){ //放在函数里面点击的时候才能执行
        fn( 400 , 400 ) //这里点击后会自执行  自执行this都是window所以要改变this的指向
      }
      oWrap.onclick = function (){ //放在函数里面点击的时候才能执行
        fn( 400 , 400 ) //这里点击后会自执行  自执行this都是window所以要改变this的指向
      }

====改变this的指向
      function fn( x , y ){
          console.log( this );
          this.style.width = x + 'px';
          this.style.height = y + 'px';
      }
      oBox.onclick = function (){ 
        var a = this;//这里this指向触发函数本身
        fn.call( a , 400 , 400 ) 
      }
      oWrap.onclick = function (){ 
        var a = this; //这里this指向触发函数本身
        fn.call( a , 500 , 800)  //改写成这样就可以随便改值
      }
    </script>
</body>

注意事项:

 function fn( x , y ){
          console.log( this );
          this.style.width = x + 'px';
          this.style.height = y + 'px';
      }
      oBox.onclick = function (){ 
        fn.call(oBox , 400 , 400 ) //这里也可以,闭包问题oBox不会被回收,占用内存,用oBox不好
      }
      oWrap.onclick = function (){ 
        fn.call( oWrap , 500 , 800) /这里也可以,闭包问题oBox不会被回收,占用内存,用oBox不好
      }


用 apply 也可以

bind方法
1、在函数定义的时候改变this的指向
2、不会帮函数执行,call apply会帮函数执行
3、不支持IE8及以下

call和apply 
function a(){
  console.log( this );
}
document.onclick = a.call( window );//===>还没点击就执行了  call会帮函数执行;


bind
function a(){
  console.log( this );
}
document.onclick = a.bind( window );//===>点击的时候才会执行  bind不会帮函数执行

bind注意事项

1、定义一个函数的时候

function a(){
  console.log( this );
}.bind( window ) //不能直接在这里设置bind,这里是在直接定义一个a的函数;
document.onclick = a;

要在这里写
function a(){
  console.log( this );
}
document.onclick = a.bind( window );

2、匿名函数的时候

oBox.onclick = function (){
    console.log( this );
}.bind( window );
匿名函数可以直接再后面定义

function fn( a ){
    a();
}
fn(
      function (){
         console.log( this ); //弹出 数学对象 
      }.bind( Math )
)
这里把一个函数当参数传进去,fn()执行函数

不能在定义的时候改this,当函数执行的时候才能改this指向

之前的案例可以写成:

<body>
    <div id='box'></div>
    <div id="wrap"></div>
    <script>
        var oBox = document.getElementById( 'box' );
        var oWrap = document.getElementById( 'wrap' );
        oBox.onclick = fn.bind( oBox , 500 , 500);//这里不会产生闭包,没有函数套函数
        oWrap.onclick = fn.bind( oWrap , 400 , 300);//这里不会产生闭包,没有函数套函数
        function fn( x , y ){
            console.log(this);
            this.style.width = x + 'px';
            this.style.height = y + 'px';
        }
    </script>

兼容写法

if( !Function.prototype.bind ){
            Function.prototype.bind = function ( This ) {
                var bindThid = this;  //这里的this是指向调用它的
                
                //第一个arguments[0] 是this 现在要把参数切出来
                var arg = [].slice.call( arguments , 1);  //[].slice()利用数组来调用slice  
                                                            // slice()里面有this 利用call改变要切割的对象
                return function (  ) {
                    bindThid.apply( This , arg )
                }
            }
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容

  • JavaScript的组成 JavaScript 由以下三部分组成:ECMAScript(核心):JavaScri...
    纹小艾阅读 3,205评论 0 3
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,149评论 0 13
  • 1.几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构? 基本数据类型:Undefined、Nul...
    极乐君阅读 5,514评论 0 106
  • 去年,我来到了这个大学。我看见她慈悲,安静的看着我,而我,心中满是沸腾的火。期待,到无奈,有话要讲,却又讲不出来...
    猫橙阅读 80评论 0 1
  • 总觉得男人之间的情谊是爽朗厚重带着义气的味道,因为足够大度宽容。男人之间打完架又勾肩搭背一起喝酒海吹的多的是,女人...
    萌芽叮当阅读 5,053评论 56 55