js 深刻 —— 从数据类型到原型链

1、数据类型

javascript中的数据类型能够分为两种类型, 基本数据类型引用数据类型。其中基本数据类型包括 String, Number, Boolean, null, undefined, Symbol(ES6)六大数据类型,引用数据类型 object
  1. 一般,数值、字符串、布尔值这三种类型,合称为原始类型,
  2. 对象则称为合成类型(complex type)的值,由于一个对象每每是多个原始类型的值的合成,能够看做是一个存放各类值的容器。
  3. 至于undefined和null,通常将它们当作两个特殊值。
这里所讲的合成类型object,其实式一个广义的对象,他包括三个子类型,[ 狭义的对象arrayfunction]

咱们通常所说的对象都是狭义的对象。javascript

基本数据类型是按照值进行分配的,是存放在了栈内存的数据片断,能够直接访问到。引用数据类型则是存放在堆内存中的数据,例如: var a = {}; a只是存储了{}的指针,这个指针指向了内存的地址。java

检测数据类型web

javascript中可使用typeof操做符来判断数据类型。可是typeof null = object; 这是历史遗留的bug;数组

typeof 123;               // "number"
typeof "hfhan";           // "string"
typeof true;              // "boolean"
typeof null;              // "object"  独一份的不同凡响
typeof undefined;         // "undefined"
typeof Symbol("hfhan");   // "symbol"
typeof function(){};      // "function"   // 这里不是object哦~~~
typeof {};                // "object"
typeof window             // "object"
typeof {}                 // "object"
typeof []                 // "object"

null是一个表示“空”的对象,转为数值时为0undefined是一个表示”此处无定义”的原始值,转为数值时为NaNpromise

null和undefined的用法于含义

null表示空值,即该处的值如今为空。调用函数时,某个参数未设置任何值,这时就能够传入null,表示该参数为空。好比,某个函数接受引擎抛出的错误做为参数,若是运行过程当中未出错,那么这个参数就会传入null,表示未发生错误。浏览器

undefined表示“未定义”,下面是返回undefined的典型场景。app

// 变量声明了,但没有赋值
var i;
i // undefined

// 调用函数时,应该提供的参数没有提供,该参数等于 undefined
function f(x) {
  return x;
}
f() // undefined

// 对象没有赋值的属性
var  o = new Object();
o.p // undefined

// 函数没有返回值时,默认返回 undefined
function f() {}
f() // undefined
能够转换为false的值
undefined
null
false
0
NaN
""或''(空字符串)

2、对象类型

宿主环境函数

通常宿主环境由外壳程序建立于维护,只要是可以提供js引擎执行环境都称为是外壳程序。如:web 浏览器, 桌面应用程序等。大数据

即由web浏览器、桌面应用程序等的外壳程序所造就的环境就是宿主环境this

js对象的分类

js的对象能够分为三类:内部对象 宿主对象 自定义对象

1. 内部对象

1.1 本地对象

ECMA-262把本地对象定义为是: 独立于宿主环境的ECMASCRIPT实现所提供的对象。

本地对象包含Object Function Boolean String Array Date RegExp Number 以及各种错误对象(Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError

1.2 内置对象

ECMA-262把内置对象定义为是: 由 ECMAScript 实现提供的、独立于宿主环境的全部对象,在 ECMAScript 程序开始执行时出现。意味着你不须要明确实例化就能够是直接使用。

包括由 Global Math两个内置对象。

global

global对象算是一个比较特殊的对象了吧,由于无论你从哪一个角度看,它都是不存在的。全局做用域下的一些属性和方法好比: isNaN parseInt等。都是global的属性和方法。
JavaScript 全局对象参考手册

2. 宿主对象

宿主对象就是执行JS脚本的环境提供的对象。对于嵌入到网页中的JS来讲,其宿主对象就是浏览器提供的对象,因此又称为浏览器对象(BOM)

不一样的浏览器提供的宿主对象可能不一样,即便提供的对象相同,其实现方式也截然不同!这会带来浏览器兼容问题,增长开发难度。

浏览器对象有不少,如WindowDocument等等。

对于web浏览器而言, Global有一个代言人 window,可是window并非ECMAScripta规定的内置对象,由于window对象是相对于web浏览器而言的,而js不只仅能够用在浏览器中。

document对象是window对象的一个属性,是显示于窗口内的一个文档。而window对象则是一个顶层对象,它不是另外一个对象的属性。document能够理解为文档,就是你的网页,而window是你的窗口,就是你的浏览器打开所显示的哪一个窗口。

3. 自定义对象

顾名思义,就是开发人员本身定义的对象。JavaScrip容许使用自定义对象,使JavaScript应用及功能获得扩充


3、判断对象的类型

使用Object.prototype.toString()来判断。

Object.prototype.toString.apply(new Function); // "[object Function]"
Object.prototype.toString.apply(new Object);       // "[object Object]"
Object.prototype.toString.apply(new Date);         // "[object Date]"
Object.prototype.toString.apply(new Array);        // "[object Array]"
Object.prototype.toString.apply(new RegExp);       // "[object RegExp]"
Object.prototype.toString.apply(new ArrayBuffer);  // "[object ArrayBuffer]"
Object.prototype.toString.apply(Math);             // "[object Math]"
Object.prototype.toString.apply(JSON);             // "[object JSON]"
var promise = new Promise(function(resolve, reject) {
    resolve();
});
Object.prototype.toString.apply(promise);          // "[object Promise]"

下面正式进入咱们的正题

4、构造函数

在javascript中对象的建立有两种方式,对象字面量构造函数

4.1 对象字面量

var o1 = {  
    p:”I’m in Object literal”,  
    alertP:function(){  
        alert(this.p);  
    }  
}  
// 这种写法不须要定义构造函数,所以不在本文的讨论范围以内。这种写法的缺点是,每建立一个新的对象都须要写出完整的定义语句,不便于建立大量相同类型的对象,不利于使用继承等高级特性。

4.2 构造函数(构造器)

new表达式是配合构造函数使用,能够实现更好的效果

new String(“a string”)
// 调用内置的String()方法来构建了一个字符串对象。



function CO(){  
    this.p = “I’m in constructed object”;  
    this.alertP = function(){  
        alert(this.p);  
    }  
}  
var o2 = new CO();
针对new操做符号在调用构造函数,咱们来刨析一下具体发生了什么

发生了四件事

var obj = {}; // 第一步建立一个空对象
obj.__proto__ = CO.prototype; // 让空对象的成员指向构造函数的prototype成员对象
CO.call(obj); // 第三步,将构造函数的做用域赋值给新的对象
return obj; // 返回新的对象
  • 注意
function C2(a, b){  
    this.p = a + b;  
    this.alertP = function(){  
        alert(this.p);  
    }  
    return this.p;//此返回语句在C2做为构造函数时没有意义  
}  
var c2 = new C2(2,3);  
c2.alertP();//结果为5  
alert(C2(2, 3)); //结果为5  

// 该实例是可行的,可是不推荐哦,
// 该函数既能够用做构造函数来构造一个对象,也能够做为普通的函数来使用。用做普通函数时,它接收两个参数,并返回二者的相加的结果。为了代码的可读性和可维护性,建议做为构造函数的函数不要掺杂除构造做用之外的代码;一样的,通常的功能函数也不要用做构造对象。

以上两种方式中展示的都是咱们自定义的对象,看了两种建立对象对的方式,咱们来结合内部对象来继续分析:

4.3 普通建立法

一个函数能够经过下面的方式直接建立。

function a(){

}

建立一个对象例如是object 能够是 {} ,建立数组能够是[], 建立正则能够是/.*/

4.4 构造函数建立对象

var a = new Function(){

}
var b = new Object({a:1})
var c = new Array(10)
var d = new Date()
var e = new Set()

咱们直接(new)使用内部对象的构造函数就能够建立一个对象了。

// 除了内置的一些对象以外,咱们还可使用普通的函数来构建对象。

function person (){
}

var p1 = new Person();
  • 咱们约定普通函数以小写字母开头,构造函数以大写字母开头。

5、原型以及原型链

未完待续
相关文章
相关标签/搜索