资讯专栏INFORMATION COLUMN

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

FWHeart / 3146人阅读

摘要:检测数据类型中可以使用操作符来判断数据类型。调用函数时,某个参数未设置任何值,这时就可以传入,表示该参数为空。我们约定普通函数以小写字母开头,构造函数以大写字母开头。五原型以及原型链未完待续

一、数据类型
javascript中的数据类型可以分为两种类型,基本数据类型引用数据类型。其中基本数据类型包括String, Number, Boolean,null,undefined,Symbol(ES6)六大数据类型,引用数据类型object

通常,数值、字符串、布尔值这三种类型,合称为原始类型,

对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。

至于undefined和null,一般将它们看成两个特殊值。

这里所讲的合成类型object,其实式一个广义的对象,他包括三个子类型,[狭义的对象arrayfunction]

我们一般所说的对象都是狭义的对象。

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

检测数据类型

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是一个表示”此处无定义”的原始值,转为数值时为NaN

null和undefined的用法于含义

null表示空值,即该处的值现在为空。调用函数时,某个参数未设置任何值,这时就可以传入null,表示该参数为空。比如,某个函数接受引擎抛出的错误作为参数,如果运行过程中未出错,那么这个参数就会传入null,表示未发生错误。

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

// 变量声明了,但没有赋值
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
""或""(空字符串)
二、对象类型

宿主环境

一般宿主环境由外壳程序创建于维护,只要是能够提供js引擎执行环境都称为是外壳程序。如:web 浏览器, 桌面应用程序等。

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

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应用及功能得到扩充

三、判断对象的类型

使用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]"

下面正式进入我们的正题

四、构造函数

在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();

我们约定普通函数以小写字母开头,构造函数以大写字母开头。

五、原型以及原型链

未完待续

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94354.html

相关文章

  • JS程序

    摘要:设计模式是以面向对象编程为基础的,的面向对象编程和传统的的面向对象编程有些差别,这让我一开始接触的时候感到十分痛苦,但是这只能靠自己慢慢积累慢慢思考。想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。 JavaScript 中的构造函数 学习总结。知识只有分享才有存在的意义。 是时候替换你的 for 循环大法了~ 《小分享》JavaScript中数组的那些迭代方法~ ...

    melody_lql 评论0 收藏0
  • 深入理解JavaScript

    摘要:深入之继承的多种方式和优缺点深入系列第十五篇,讲解各种继承方式和优缺点。对于解释型语言例如来说,通过词法分析语法分析语法树,就可以开始解释执行了。 JavaScript深入之继承的多种方式和优缺点 JavaScript深入系列第十五篇,讲解JavaScript各种继承方式和优缺点。 写在前面 本文讲解JavaScript各种继承方式和优缺点。 但是注意: 这篇文章更像是笔记,哎,再让我...

    myeveryheart 评论0 收藏0
  • 关于个人第一天前端面试的面试问答QA,希望能对其他找前端工作的朋友有所帮助。

    摘要:两日前,发了一篇吐槽,莫名的火了一把。关于的第一个,其实就是声明一个常量,不允许变更。另外对象迭代这里出自,阮一峰大神写的入门指南,对象篇。 两日前,发了一篇吐槽,莫名的火了一把。经过大家的建议与鼓励,于是修改了简历,开始了重新投递,2天后接到第一份面试邀请。 此文为个人面试经历,QA问答过程与总结,不透露面试公司及面试人员,内容真实,如果有面试过我的大佬看到博客,欢迎指出问题。 循序...

    Youngdze 评论0 收藏0
  • JS原型原型深入理解

    摘要:如果要理清原型和原型链的关系,首先要明确一下几个概念中的所有东西都是对象,函数也是对象而且是一种特殊的对象中所有的东西都由衍生而来即所有东西原型链的终点指向对象都有一个隐藏的属性,他指向创建它的构造函数的原型,但是有一个例外,指向的是。 首先要搞明白几个概念: 函数(function) 函数对象(function object) 本地对象(native object) 内置对象(bu...

    Alex 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<