this指向 - Node环境

1.全局上下文中 this

/*
1.全局上下文中的 this

node环境下:

    严格模式下: {} {} 报错

    非严格模式下:{} {} {}
 */

‘use strict‘; // 严格模式

// demo 1:
console.log(this);  // {}

// demo 2:
var a = this;
console.log(a); // {}
var b = 1;
console.log(global.b); // undefined

// demo 3:
b = this; // 注意:严格模式下,变量必须得声明;非严格模式,可以省略声明符
console.log(b); // {}
c = 1;
console.log(global.c); // 1

/*
分析:

    node环境下:

    node环境下 的上下文组成 与 浏览器环境下 有些不同;

    扩展了解一下,Node.js的全局对象 global:

    定义:Node.js中的全局对象是 global, 所有全局变量(除了 global 本身以外)都是global对象的属性;

    在 Node.js 中,我们可以直接访问到 global属性,而不需要在应用中包含它;

    也就是说,global 是全局对象,但是它还是 global.global的属性值,这是递归的过程;

    这跟浏览器下的 window对象 是一个逻辑,window对象还是 window.window 的属性值;

    全局对象 与 全局变量的关系:

    global的根本作用是作为全局变量的宿主,按照 ECMAScript的定义,满足以下条件的变量为全局变量:

        1.在最外层定义的变量

        2.全局对象的属性

        3.隐式定义的变量(未定义直接赋值的变量)

    当你定义一个全局变量时,这个变量同时也会成为全局对象的属性,反之亦然。需要注意的是,在 Node.js中你不可能在最外层定义变量,

    因为所有用户代码都是属于当前模块的,而模块本身不是最外层上下文。

    注意:永远使用 var 定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。

    所以,以上三个demo 获取 this 的方式:

    demo 1: 直接获取 this, 实际上 demo 1 创建执行上下文的过程是在 当前模块中进行的,所以说这个模块的上下文环境才是,demo 1 代码执行时的执行上下文,

        也就是说 环境对象是当前模块对象,而这个模块对象是个 新对象{},而结果输出 {}, 也就符合“this 指向其执行上下文的环境对象”这一结论了;

    demo 2: 根据定义,由于用var 声明的变量,实际上并不是在最外层上下文中声明的变量,是在当前模块声明的变量(global.b 值为 undefined,已经证明这点了),

        但是,整个代码的执行过程还是在 当前模块的上下文中进行的,同上 输出 {},也就符合“this 指向其执行上下文的环境对象”这一结论;

    demo 3: 可以看出 demo 3 在非严格模式下隐式定义了一个变量,并且给它赋了值,根据全局变量的定义,这样隐式定义变量的方式,

        实际上是在全局对象上定义一个属性,也称为全局变量,所以 通过 global对象可以获取到(global.c 的值为 1,已证明这点);

        但是要弄清楚,在这个全局变量的 定义过程,还是在 当前模块进行的,所以 此时 this指向依然是 当前模块的执行上下文对象 {};

        所以,“this 指向其执行上下文的环境对象” 这一结论依然成立;

总结:

    Node环境下:

        全局的执行上下文 进行的过程是在 当前模块下进行的,所以全局执行上下文的环境对象是当前模块{},所以全局中 this 指向当前模块对象{};
 */

2.函数上下文的 this

/*
    2.函数上下文中的 this

    Node环境下:

        严格模式下: this 指向被指定的环境对象,即使指定的是 null 或者 undefined;

        非严格模式下:this 指向被指定的环境对象,如果指定的是 null 或者 undefined,会转为全局对象 global对象;
     */

"use strict"

// demo 1:
function aa(){
    console.log(this);
}

aa(); // 作为单独函数执行(没有指定 环境对象):strict-->"undefined"    nostrict-->"global"

// demo 2:
var obj = {
    a: 1,
    b: function(){
        console.log(this);
    }
}

obj.b(); // 作为对象方法执行: strict-->obj    nostrict-->obj

// demo 3:
aa.call(obj); // 作为单独函数执行(指定 环境对象为 obj): strict-->obj    nostrict-->obj

// demo 4:
aa.call(null); // 作为单独函数执行(指定 环境对象为 null):strict-->null    nostrict-->global

// demo 5:
aa.call(undefined); //作为单独函数执行(指定 环境对象为 undefined):strict-->undefined    nostrict-->global 

/*
总结:函数上下文中的 this

Node环境 严格模式下:

    函数作为单独函数 执行:

        1.函数执行上下文的环境对象 是指定的,指定什么就是什么;this指向这个指定的环境对象;即使指定的是 null 或者 undefined;

    函数作为对象方法 执行:

        2.这个函数执行上下文的环境对象就是这个拥有它的对象;this指向这个拥有它的对象;

Node环境 非严格模式下:

    函数作为单独函数 执行:

        1.函数执行上下文的环境对象 是指定的,指定什么就是什么;this指向这个指定的环境对象,如果指定的是 null 或者 undefined,会转为全局对象 global对象; 

    函数作为对象方法 执行:

        2.这个函数执行上下文的环境对象就是这个拥有它的对象;this指向这个拥有它的对象;
 */

3.对象属性中的 this

/*
    3.对象属性中的 this

    注意:这里指的是如下的形式,不要把它和 对象方法中的 this搞混;对象方法中的 this,要规划到 函数上下文的 this中; 

    Node环境下:

        严格模式下:{}

        非严格模式下: {}
 */
‘use strict‘
var obj = {
    a: 1,
    b: 2,
    c: this,
    sayHi: function(){
        console.log(‘Hi‘);
    }
}

console.log(obj.c);    // {}

/*
    分析:

        其实,这样的对象字面量的形式,可能看起来会有些困惑,我们可以变形来分析;因为对象字面量的形式,实际上是由如下的形式简化而来的写法;

        var obj = new Object();
        obj.a =1;
        obj.b = 2;
        obj.c = this;
        obj.sayHi = function(){
            console.log(‘Hi‘);
        }

        这样看来就清晰很多了,上边这段代码执行的时候,不就是把全局执行上下文的环境对象赋给 obj.c 属性吗,关于 Node中全局上下文的环境对象 为 一个新对象{},我们已经介绍过了;

        而且结果,也正符合我们此时所得出的结果;

        所以,这样作为对象中的 this,可以规到全局执行上下文中的 this 一类中,this 指向 全局执行上下文的环境对象{};
*/
/*
    一个例子,可能没有什么说服力,我们再来个嵌套形式的 来证实我们的结论, 如下:
 */
var o1 = {
    a: 1,
    b: this,
    o2: {
        a: 1,
        b: this
    }
}

console.log(o1.o2.b); // {}
/*
    结果依然是 {}, 其实 如上的形式,可以变形为:

    var o1 = new Object();
    o1.a = 1,
    o1.b = this;
    o1.o2 = new Object();
    o1.o2.a = 1;
    o1.o2.b = this;

    上面这段代码 在执行时,它的执行上下文的环境对象依然是 全局上下文的环境对象;所以说 this依然指向 {};

 */

/*
    概括:对象属性中的 this指向为 全局执行上下文的环境对象{};
*/

4.构造函数 和 原型方法中的 this

/*
    4.构造函数 和 原型方法中的 this

    浏览器环境下:

        严格模式下:以构造函数名命名的新对象

        非严格模式下: 以构造函数名命名的新对象
 */
     "use strict"

     function Person(){

        console.log(this);    // Person {}

        this.name = ‘jack‘;

        console.log(this);    // Person {name: "jack"}
    }

    Person.prototype.sayThis = function(){
        console.log(this);
    }

    Person.prototype.sayThis();    // {sayThis: ?}

    new Person();    // Person {} --> // Person {name: "jack"}

    /*
    分析 1:

        构造函数与普通函数的最重要的不同之处,就是构造函数可通过 new操作符,创造实例;

        那么在利用构造函数创造实例的过程到底发生了什么呢? 其实呢,是要经历以下几个过程的:

            1.创造一个 新对象,作为执行上下文的环境对象;(注意:这里为什么说成是新对象,而不说成是空对象呢,因为 function默认是有 prototype属性存在的,它指向原型对象)

            2.构造函数开始执行,它的执行上下文环境对象就为这个新对象,也就是说 this指向这个新对象;

            3.利用 this来给这个新对象赋值;

            4.返回这个被赋值之后的 新对象;

        通过上面 new Person() 执行后输出的结果来看,确实是这样的一个过程;没有没给 this赋值前输出的是 Person{}, 赋值后,输出的 Person{name:‘jack‘};

        所以 概括:

            构造函数中的执行上下文的环境对象为,以构造函数名命名的新对象;

    分析 2:

        至于原型方法中 this, 其实,在我们了解了 “函数上下文的 this” 之后,应该很清楚了,它指向给它指定的环境对象,也就是确定了的 构造函数的原型对象;

        所以,Person.prototype.sayThis() 执行后,输出的结果是 Person构造函数的原型对象 --> Person.prototype 对象;
     */

5.应用 call、apply、bind 方法后的 this

    /*
    5.应用 call、apply、bind 方法后的 this

    了解:call、apply、bind 这三个方法是 Function对象才有的方法;它们的作用,主要是指定函数中 this中的指向,只是用法稍有不同;

    浏览器环境下:

        严格模式下:this指向 这三个方法所指定的这个值,无论是什么,即使是 null、undefined, this 也指向它们;

        非严格模式下:this指向 这三个方法所指定的这个值,null 和 undefined 值会被转换为全局对象 window;

     */

    "use strict"

    // demo 1:
    var o1 = {
        a: 11,
        b: 12,
        sayA: function(){
            console.log(this.a);
        }
    }

    var o2 = {
        a: 21,
        b: 22
    }

    o1.sayA.call(o2);    // 21

    // demo 2:
    function sayB(){
        console.log(this.b);
    }

    sayB.call(o2);    // 22
    sayB.apply(o2);    // 22

    var bSayB = sayB.bind(o2);
    bSayB();        // 22

    /*
    其实这块不应该单提出来一个作总结分析的,完全可以规划到“函数上下文的 this”中去,只是在我们平时 coding的时候, 

    这三个方法是经常要用到的 所以单拿出来,以作记忆吧;

     */    

原文地址:https://www.cnblogs.com/cnblogs-jcy/p/8909929.html

时间: 2024-08-29 04:05:24

this指向 - Node环境的相关文章

node环境和浏览器的区别

正好最近有朋友咨询我这个问题,那就简单谈一下我理解的node环境和浏览器的区别,高手请略过. 一.全局环境下this的指向 在node中this指向global而在浏览器中this指向window,这就是为什么underscore中一上来就定义了一 root: 1 var root = typeof self == 'object' && self.self === self && self || 2 typeof global == 'object' &&

node环境配置安装(nvm)

在我们前端开发工程中,很多繁琐机械的操作都是会慢慢的被抽离出来的,当我们为dom操作和浏览器兼容性感到厌烦时,jQuery出现了,当我们不想再去理会dom的添加删除等的时候,angularJS来解救我们,那么,随着时间的发展,我们前端开发的王牌语言JavaScript,现在被应用到了服务器中,对的,这是一个里程碑式的创新,今后,你不再需要去使用php/.net等后端语言,仅仅使用JavaScript就可以前端后端通吃,这就是web全栈工程师吧!神奇的node.js为我们JavaScript提供了

服务器上安装搭建node环境

一.版本 : node  v4.4.3 npm  v2.15.1 pm2  v1.1.3 express v4.13.4 二.node安装与环境配置 新建node安装目录,与node项目目录 sudo mkdir -p /www/dev/node 2.进入node目录,下载node二进制文件包(免编译) sudo  wget https://nodejs.org/dist/v4.4.3/node-v4.4.3-linux-x64.tar.gz 如果wget 不可用,可先下载wget    : 

Node环境

Node环境 1. node.js介绍 node.js是Server side javascript runtime,即服务端的js运行时.js运行在浏览器内核中,node.js可理解为js的运行环境,可以在node中运行JS代码. JS由ECMAScript.DOM.BOM三部分组成,node中只能运行ECMAScript,无法使用BOM和DOM. node将浏览器JS引擎(chrome的V8引擎)搬到了服务器端,增加了一些提供文件.网络之类操作的API. node.js内置http服务器(P

win8 系统安装node环境记录

原先我是用win7环境安装node很方便,到了win8系统突然变了,让我顿时困惑了一段时间,但还是被我找到方式解决了,记录一下解决方案: 首先在网上看了一些资料说win8下安装node环境会出错,但我的本子没有出现这个状况,直接在nonde官方网站下载镜像 我是win8 64位 直接找到对应的下载.下载完安装node.js就不用说了,安装基本常识. 这是第一步,node基础环境安装完成,直接在cmd中输入 说明安装node 成功,接下来我要安装express 注意:一般用npm下载 node组件

4.创建OpenStack的node环境脚本

创建OpenStack的node环境脚本 使用source admin-openrc.sh来运行脚本 在任意目录下创建admin-openrc.sh文件 vim ~/admin-openrc.sh export OS_TENANT_NAME=admin export OS_USERNAME=admin export OS_PASSWORD=Abcd1234 export OS_AUTH_URL=http://controller:35357/v2.0 在任意目录下创建 demo-openrc.s

Node.js(window)基础(2)——node环境下的模块,模块间调用

参考:http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434502419592fd80bbb0613a42118ccab9435af408fd000 1.node环境下的模块(module)概念:一个name.js文件就是一个模块,name是模块名称,模块中的函数方法称之为变量. 2.模块变量的调用:A.js中输出变量module.exports=函数名称; B.js引入模

Linux下配置Node环境变量及问题详解

这是之前在Linux下配置Node环境变量时踩过的坑,今天又有小伙伴质询这个问题,因此记录下来,不仅是给新童鞋们一些参考,也方便日后查阅 在这之前,相信都已经安装好了,没安装的可以查看博主另一篇文章  ---------http://www.cnblogs.com/Halifa/p/5772263.html 配置Node环境变量有永久生效和当时生效几种方式,这里只讲解永久生效 进入主题: 修改/etc/profile文件,在末尾添加以下内容 export NODE_HOME=/usr/local

非node环境 vue-rouder 学习笔录1

在非node环境中 需要我们在文本中引入vue.js 和vue-rouders.js首先引用<script src="https://unpkg.com/vue/dist/vue.js"></script><script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>现在做个简单的例子<div id="app"&g