JavaScript高等程序设计——this

《JavaScript高等程序设计——this》

媒介

原本this应当放在《上下文环境和作用域》中来讲,效果发明本身整顿的时刻,例子越来越多,所以零丁写一篇用于加深明白,今后事情或项目中发明一些this相干题目能够进一步完美文章的例子。

this

观点

在函数中this究竟取何值,是在函数真正被挪用实行的时刻肯定的,函数定义的时刻肯定不了

由于this的取值是实行上下文环境的一部分,每次挪用函数,都邑发生一个新的实行上下文环境。

组织函数

所谓组织函数就是用来new对象的函数。实在严格来讲,一切的函数都能够new一个对象,然则有些函数的定义是为了new一个对象,而有些函数则不是。别的注重,组织函数的函数名第一个字母大写(划定规矩商定)。比方:Object、Array、Function等。

function Foo() {
            this.name = "yzh";
            this.year = 1996;
            console.log(this); //Object { name: "yzh", year: 1998 }
        }
        var f1 = new Foo();
        console.log(f1.name); //yzh
        console.log(f1.year); //1996

以上代码中,假如函数作为组织函数用,那末个中的this就代表它行将new出来的对象。

注重,以上仅限newFoo()的状况,即Foo函数作为组织函数的状况。假如直接挪用Foo函数,而不是new Foo(),状况就大不一样了。

function Foo() {
            this.name = "yzh";
            this.year = 1996;
            console.log(this); //Object { name: "yzh", year: 1998 }
        }
        Foo();  //window

这类状况下this是window。

函数作为对象的一个属性

假如函数作为对象的一个属性时,而且作为对象的一个属性被挪用时,函数中的this指向该对象。

var obj = {
            x: 10,
            fn: function() {
                console.log(this); //Object { x: 10, fn: fn() }
                console.log(this.x); //10
            }
        };
        obj.fn();

以上代码中,fn不仅作为一个对象的一个属性,而且的确是作为对象的一个属性被挪用。效果this就是obj对象。

假如fn函数不作为obj的一个属性被挪用,会是什么效果呢?

var obj = {
            x: 10,
            fn: function() {
                console.log(this); //window
                console.log(this.x); //undefined
            }
        };
        var f1 = obj.fn;
        f1();

如上代码,假如fn函数被赋值到了另一个变量中,并没有作为obj的一个属性被挪用,那末this的值就是window,this.x为undefined。

函数用call或许apply挪用

为了防备看不懂这块先明白下基本并重要的东西

函数内部属性

在函数内部,有两个特别的对象:arguments和this.
重要引见下arguments,它是类数组对象,包括传入函数的一切参数,这个对象另有一个叫callee的属性,该属性为一个指针,指向具有这个arguments对象的函数。

这个例子重要用于消弭函数的实行与同名函数的严密耦合征象。代码以下:

function factorial(num) {
            if (num <= 1) {
                return 1;
            } else {
               // return num * factorial(num - 1);
                //1.平常的递归算法应用
                return num * arguments.callee(num - 1) 
                //2.更好的做法
            }
        }

        var trueFactorial = factorial;

        factorial = function() {
            return 0;
        };

        alert(trueFactorial(5)); //120
        alert(factorial(5)); //0

函数属性

每一个函数都包括两个属性:length和prototype.
length示意函数愿望接收的定名参数的个数

function sayName(name){
            alert(name);
        }      
        
        function sum(num1, num2){
            return num1 + num2;
        }
        
        function sayHi(){
            alert("hi");
        }
        
        alert(sayName.length);  //1
        alert(sum.length);      //2
        alert(sayHi.length);    //0

prototype属性这里不再反复引见。

函数要领

每一个函数都包括两个非继续而来的要领:apply()和call(),这两个要领的用处都是在特定的作用域中挪用函数,实际上即是设置函数体内的this对象值

apply()要领接收两个参数:一个是在个中运转函数的作用域,另一个是参数数组。

function sum(num1, num2){
            return num1 + num2;
        }
        
        function callSum1(num1, num2){
            return sum.apply(this, arguments);
        }
        
        function callSum2(num1, num2){
            return sum.apply(this, [num1, num2]);
        }
        
        alert(callSum1(10,10));   //20
        alert(callSum2(10,10));   //20

callsSum1()实行sum()函数时传入this作为this值(在全局作用域中挪用,所以传入的对象为window对象)下面的例子同理。

call()要领与apply()要领差不多,区分在于接收参数的体式格局差别。简朴来讲就是:通报给函数的参数必需逐一枚举出来。(假如是无参函数就不必传参数)

function sum(num1, num2){
            return num1 + num2;
        }
        
        function callSum(num1, num2){
            return sum.call(this, num1, num2);
        }
        
        alert(callSum(10,10));   //20

通报参数并不是两个函数的真正用武之地,真正壮大的处所是扩大函数赖以运转的作用域

window.color = "red";
        var o = { color: "blue" };
        
        function sayColor(){
            alert(this.color);
        }
        
        sayColor();            //red
        
        sayColor.call(this);   //red
        sayColor.call(window); //red
        sayColor.call(o);      //blue

以下代码假如不必函数的要领来完成。

window.color = "red";
        var o = { color: "blue" };
        
        function sayColor(){
            alert(this.color);
        }
        
        sayColor();     //red
        
        o.sayColor = sayColor;
        o.sayColor();   //blue

假如要输出o对象里的color属性值,必需把sayColor函数赋给对象o并挪用 o.sayColor()时,this援用的对象为o

回归要讲的例子

当一个函数被call和apply挪用时,this的值就取传入的对象的值。

var obj = {
            x: 10
        };
        var fn = function() {
            console.log(this); //Object { x: 10 }
            console.log(this.x); //10
        };
        fn.call(obj);

全局 & 挪用一般函数

在全局环境下,this永远是window,这个应当没有非议。

console.log(this === window); //true

一般函数在挪用时,个中的this也都是window。

var x = 10;
        var fn = function() {
            console.log(this); //window
            console.log(this.x); //10
        }
        fn();

注重以下的状况

var obj = {
            x: 10,
            fn: function() {
                function f() {
                    console.log(this); //Window 
                    console.log(this.x); //undefined
                }
                f();
            }
        };
        obj.fn();

函数f虽然是在obj.fn内部定义的,然则它依然是一个一般的函数,this依然指向window。

总结:this指向挪用该函数的对象

组织函数的prototype中,this代表着什么

function Fn() {
            this.name = "yzh";
            this.year = 1996;
        }
        Fn.prototype.getName = function() {
            console.log(this.name);
        }
        var f1 = new Fn();
        f1.getName(); //yzh

在Fn.prototype.getName函数中,this指向的是f1对象。因而能够经由过程this.name猎取f1.name的值

bind()

bind()要领建立一个新的函数, 当被挪用时,它的this关键字被设置为供应的值 ,在挪用新函数时,供应任何一个给定的参数序列。

这个函数实在也很重要,只是当时红宝书也没说起许多。

语法

fun.bind(thisArg[, arg1[, arg2[, …]]])

参数

thisArg

当绑定函数被挪用时,该参数会作为原函数运转时的 this 指向。当运用new 操作符挪用绑定函数时,该参数无效。

arg1, arg2, …

当绑定函数被挪用时,这些参数将置于实参之前通报给被绑定的要领。

返回值

返回由指定的this值和初始化参数革新的原函数拷贝

形貌

bind() 函数会建立一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目的函数)具有雷同的函数体(在 ECMAScript 5 范例中内置的call属性)。当目的函数被挪用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被挪用时,bind() 也接收预设的参数供应给原函数。一个绑定函数也能运用new操作符建立对象:这类行动就像把原函数当做组织器。供应的 this 值被疏忽,同时挪用时的参数被供应给模仿函数。

示例

建立绑定函数

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这类状况下,"this"指向全局作用域

// 建立一个新函数,将"this"绑定到module对象
// 新手能够会被全局的x变量和module里的属性x所疑惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

End

迎接拍砖,有更多的好的例子,迎接提出,文中有误的处所也迎接斧正。

    原文作者:cduyzh
    原文地址: https://segmentfault.com/a/1190000009476135
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞