JS----数据类型 作用域 作用域链 执行环境 执行顺序 闭包的理解

1.js中的数据类型有以下几种:

  Number   Boolean   undefined     Object   Function    String  Null
    基本类型:Number Boolean  String  undefined null
    引用类型:Object  Function

基本类型的数据是存放在栈内存中的,而引用类型的数据是存放在堆内存中的
2.判断数据类型
参考学习:http://www.cnblogs.com/ziyunfei/archive/2012/11/05/2754156.html
在 JavaScript 里使用 typeof 来判断数据类型,只能区分基本类型,即 “number”,”string”,”undefined”,”boolean”,”object” ,“function”六种。
tyoeof(null) ==object
要想区别对象、数组、函数单纯使用 typeof 是不行的,JavaScript中,通过Object.prototype.toString方法,判断某个对象值属于哪种内置类型。

例子:
var arr = [];
console.log(Object.prototype.toString.call(arr))
结果:
“[object Array]”

在ES3中,Object.prototype.toString方法的规范如下:

Object.prototype.toString()
在toString方法被调用时,会执行下面的操作步骤:

1. 如果this的值为undefined,则返回"[object Undefined]".
2.如果this的值为null,则返回"[object Null]".
3.让O成为调用ToObject(this)的结果.
4. 获取this对象的[[Class]]属性的值。
5. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串。
6. 返回第二步的操作结果Result(2)。

[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性.在规范中,[[Class]]是这么定义的:
内部属性 描述
[[Class]] 一个字符串值,表明了该对象的类型。
其过程简单说来就是:1、获取对象的类名(对象类型)。2、然后将[object、获取的类名、]组合并返回。

var arr=[1,2];
//直接对一个数组调用toString()
arr.toString();// "1,2"
判断是否为数组对象
//通过call指定arr数组为Object.prototype对象中的toString方法的上下文
Object.prototype.toString.call(arr); //"[object Array]"

判断对象类型是否为数组

function isArray(arg) {
    if (typeof arg === 'object') {
        return Object.prototype.toString.call(arg) === '[object Array]';
    }
    return false;
}

3.有关js对象(内置,原生,宿主,全局)

原生对象(内部对象,本地对象)(native object):独立于宿主环境的ECMAScript实现提供的对象。
原生对象:object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError、Global

内置对象:由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript
程序开始执行时出现,即在引擎初始化阶段就被创建好的对象。 内置对象:Global(全局对象)、Math

宿主对象:由ECMAScript实现的宿主环境提供的对象,可以理解为:浏览器提供的对象。所有的BOM和DOM都是宿主对象。
宿主对象:有宿主提供的对象,在浏览器中window对象以及其下边所有的子对象(如bom、dom等等),在node中是globla及其子对象,也包含自定义的类对象。

全局对象:全局对象:一般全局对象会有两个,一个是ecma提供的Global对象,一个是宿主提供。如在浏览器中是window、在nodejs中是global。【所以啊,在浏览器中全局对象是Global+window】
全局对象:一般全局对象会有两个,一个是ecma提供的Global对象,一个是宿主提供。 通常情况下ecma提供的Global对象对是不存在的,没有具体的对象,

内置对象之Global
Global即为全局对象,Global对象是ECMAScript中最特别的对象,因为实际上它根本不存在!
在ECMAScript中,不存在独立的函数,所有函数都必须是某个对象的方法。
类似于isNaN()、parseInt()和parseFloat()方法等,看起来都是函数,而实际上,它们都是Global对象的方法。
而且Global对象的方法还不止这些。

4.作用域 作用域链 执行环境 执行顺序 闭包的理解
变量的作用域:全局变量和局部变量。
全局作用域:最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的。
局部作用域
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部
作用域链
根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。
js的执行顺序是根据函数的调用来决定的,当一个函数被调用时,该函数环境的变量对象就被压入一个环境栈中。而在函数执行之后,栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象。
**闭包:**闭包有两个作用:
第一个就是可以读取自身函数外部的变量(沿着作用域链寻找)
第二个就是让这些外部变量始终保存在内存中
执行环境
每个函数运行时都会产生一个执行环境,js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中。
全局执行环境是最外围的执行环境,全局执行环境被认为是window对象,因此所有的全局变量和函数都作为window对象的属性和方法创建的。
执行坏境可以分为创建与执行两个阶段,在创建阶段,js解析器首先会创建一个变量对象(活动对象),它由定义在执行坏境中的变量,函数声明和参数组成,在这个阶段,系统会自动的产生一个this对象,作用域链会被初始化,随之,this的值也会被确定,
第二阶段,也就是代码执行,代码会被解释执行,你会发现,每个执行坏境都有一个与之关联的变量对象,执行坏境中所有定义的变量和函数都保存在这个对象中,注意,我们是无法手动的访问这个对象的,只有js解析器才能够访问它,其实也就是this,尽管很抽象,但是理解它还是蛮重要的

例子:

<span style="font-size:18px;">var flag=1;  
    function testChain(){  
        var flag=2;  
        function chain1(){  
            var flag=3;  
            console.log("f1: "+flag);  
        }  
        function chain2(){
            function chainChild(){
                var flag=4;
                console.log("f2: "+flag);
            }
            chainChild();  
            console.log("f3: "+flag);  
        }  
        chain1();  
        chain2();  
    }  
    console.log("f4: "+flag); 
    testChain();</span>

最终输出的结果是:f4: 1,f1: 3,f2: 4,f3: 2
对于f3的值是沿着 f3 ->chain2 -> testChain ->window 这条作用域链去找自己的值,最终在testChain上找到了值打印出来
this

  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());//result:The Window

this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。不过,匿名函数具有全局性,因此this对象同常指向window

posted @ 2019-03-21 21:01  princeness  阅读(179)  评论(0编辑  收藏  举报