1.判断对象类型
1.1.typeof 运算符
首先要认识到,typepof是一个运算符,其运算需要一个参数,返回值是参数的类型。
-
typeof使用方法
typeof parameter //使用方法1
typeof (parameter) //使用方法2....这两种方式是等效的。 -
typeof的返回值
typeof的返回值,主要有五种: undefined,boolean,number,string,object.
JavaScript主要有五种基本数据类型和一种引用数据类型,所以对于typeof的返回值,容易混淆的一点就是下面的一点
typeof null; //"object”null在js中指的是一个空对象。所以,对于typeof null =="object"也是有其道理的。
1.2.instanceof 运算符
instanceof也是一个运算符,运算过程中也需要一个参数,判断某一个对象是否是所给的构造函数的一个实例,返回值是true或者false;
- instanceof使用方法
parameter1 instanceof (parameter2) //两种方法等效
-
instanceof返回值
instanceof的返回值,只有两种 true 或者false;
1.对于基本数据类型,总是返回false;
console.log(null instanceof Object); //false
console.log(true instanceof Boolean); //false
console.log(10 instanceof Number); //false
console.log("sad" instanceof String); //false
var object={};
console.log(object instanceof Object);//true
function A(){}
console.log(A instanceof Function);//true
var B=function(){};
var b=new B();
console.log(b instanceof B);//true
1.3.instanceof的原理
typeof的原理比较简单,主要根据一个其数据类型来返回值。这里我们主要讲解下instanceof的工作原理.
看下面一道例题:
};
var Dog = function () {
};
//子类继承父类的函数
function extend(subClass, superClass) {
var prototype = Object.create(superClass.prototype);
subClass.prototype = prototype;
subClass.prototype.constructor = subClass;
}
extend(Dog, Animal);
var dog = new Dog();
console.log(dog instanceof Dog);//true
console.log(dog instanceof Animal);//true
上面的这道例子,声明了两个类,动物和狗.用狗类实例化一个对象dog.按我们的理解,dog当然属于狗这一类,当时,狗难道不是动物吗? 所以上述两种输出结果都输出true.是合理的。
上述代码执行完毕后,内存中的情况大致是这么样的!
知道了内存中的情况,下面我们来分析一下,代码的执行过程。
执行dog instanceoof Dog的时候
在判断dog对象是否是Dog类的实例的时候,
1.解释器判断dog是否是一个对象,否不是一个对象,则返回false.若是一个对象则跳到第二部。
2.解释器先取得dog的内置属性,然后去取的Dog的函数原型(prototype)。
3.比较dog的内置属性和Dog.prototype是否是同一个对象,若是则返回true.
在执行到第3步的时候,因为则返回true.该句执行结束。
执行dog instanceoof Animal的时候
按照上述步骤执行到第三部,判断dog的内置属性和Animal.prototype不是一个对象,此时接着执行下一步
4.若dog对象的内置属性和Animal类的原型不是同一个对象,则取出dog的内置属性所指向的对象的内置属性
5.判断dog内置属性所指向对象的内置属性是否和Animal.prototype是否指向同一个对象,若是则返回true.
否则,沿着对象内置属性链一直向上查找,一直追溯到null(Objece.prototype.__proto__==null)为止。
简而言之,instanceof比较的时候,
比较的规则是拿对象上的内置属性链上的所有对象与给定的构造函数的原型(prototype)一一比较,直到找到相等的为止。
若比较到最后仍然没有发现两者相等,则返回false.
2.一切皆对象
2.1.为什么说,一切皆是对象呢?
一切皆是对象,这话要从何说起呢!! 看下面的一段代码?
function a() {
};
console.log(a instanceof Object); //true
如果连函数(function)都是对象,以及函数的构造函数(Function)也是对象,那么我们的确没有理由反对一切皆是对象。但是,怎么证明函数以及函数的构造函数都是对象,这些又是怎么设计的呢?
我们知道,如果是对象。那么身为一个对象,就必须具备对象中最基本的一个属性-----内置属性(内置属性是任何对象都有的一个属性),而且,内置属性最初都起源于Object.prototype.如果这么说的话,那么,我们可以得出一个结论,即 Function和fucntion都具有一个内置属性,且该内置属性直接来自或者间接来自Object.prototype.
现在我们用代码来证明一下是不是这个样子:
如果这个输出结果是真的,那么在内存中的结构就应该是这么个样子:
说道这里,我们能解释了Function是一个对象。接着我们来解释function也是一个对象。
同样的道理,function既然是一个对象,那么肯定也有内置属性,而且function是Function的一个实例,所以其内置属性肯定来源于Function.prototype.那么Function.prototype是什么呢?
讲到这里,是不是明白了什么呢? 原来Function的内置属性和其原型属性竟然是同一个对象。 好,进行到这里,我们就来一张综合图来分析一下,function Function Object.prototype三者间的关系。
到这里我们算是揭示了一切皆是对象的设计。但是如果想要理解整个设计的架构,我们还需要搞明白一些事情?
即 从图中我们看出,
1.Function的对象的内置属性的constructor指向Function.
因为constructor指向Function ==> Function.__proto__是Function的一个实例 ==> Function.__proto__是一个函数。 ok...证明一下:
到这里也就证明了我们的推论。但是,下面的一个问题来了,所有的对象都有一个内置属性啊。换句话说,Object函数应该有一个内置的[[_proto_]]属性,而Object.prototype也应该有一个内置的[[_proto_]]属性。ok..上面的这幅图片,如果补充完整的话,结果应该如下所示:
上面这幅图片上,我们可以看出,无论一个对象的构造函数是谁,其内置属性最终会回归到最上层的Object.prototype.所以,也就是说一切皆是对象,这句话,不只是说说而已。
注: 上面的这幅图片理解起来不是那么容易。
所以,下面我们来谈谈,怎么看懂上面那副图片?
2.2.为什么要如此设计?
从美学的角度来说,上面的那种设计图真的谈不上美观,第一,它不简单,七拐八绕。第二,很难看出来图片想要表现的是什么!
看懂上面那幅图片,需要有三个最基本的指导思想,
1.一切皆是对象。
2.对象总有一个内置属性,且该内置属性指向其构造函数的prototype属性。
3.函数总有一个prototype属性,该函数在实例化的实话,该属性赋值给实例的内置属性。
明白了上面的三点,下面的几段代码,看看你是否能够回答正确?
console.log(a.__proto__ == Function.prototype);
console.log(Function.__proto__ == Function.prototype);
console.log(Function.__proto__.__proto__ == Function.prototype)
console.log(Object.__proto__ == Function.prototype); //这些代码是为了证明第二点,第一点我们在2.1中已经证明
console.log(a.__proto__ == Function.prototype);
var object={};
console.log(object.__proto__==Object.prototype) //这些代码是为了证明第三点
正因为有上述三种知道指导的存在,所以我们才会使得JS有那么眼花缭乱的效果。
现在,你按着这三种知道思想来考虑一下,是否有比上张图片更好的设计呢!!
注: 在JS中,并不是严格的面向对象,可以说,一切只是技巧的堆砌。不过,这门语言给人的启发的确可以引人深思----面向对象是否有更好的设计呢?
3.总结
总结的部分,其实就是列出一下这篇文章中写作的重点。
首先,分析下typeof和instanceof的比较,目的是掌握instanceof的工作原理。因为在第二部分中,需要大量使用这个函数。
其次,我们逐步分析,一切皆是对象这个观点。然后,用实例来证明观点。
再次,证明一切皆是对象之后,接着来分析,用图片一步步引出,整个设计的轮廓,重点是掌握最后一张图片。因为所有的目的 都是为了证明最后一张图片。
最后,提出这种设计的核心指导思想。你可以比照着这种指导思想仔细阅读第二部分。
相关推荐
深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系
在JavaScript的世界里,原型对象(Prototype)是理解对象继承机制的关键。这个练习旨在帮助学习者深入理解原型链的概念,这是JavaScript实现面向对象编程的核心部分。原生JS,即不依赖于像jQuery这样的库,让我们...
之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)的解释去描述。有一句话说的好:如果你不能把一个很复杂的东西用最简单的话语描述出来,那就说明你...
### JavaScript原型与原型链详解 JavaScript作为一门基于原型的语言,其原型和原型链的概念是理解和掌握JS继承机制的关键。接下来将详细阐述这些概念。 #### 普通对象与函数对象 在JavaScript中,一切皆为对象,...
在JavaScript中,一切皆为对象,而原型链则是实现对象间属性和方法共享的一种机制。理解原型链对于深入学习JavaScript至关重要。 首先,每个JavaScript对象都有一个内部属性`[[Prototype]]`,通常我们通过`__proto_...
JavaScript原型和闭包是这门语言中两个比较难以理解且与其他面向对象语言区别较大的概念。理解这两个概念,不仅能让我们更深层次地理解JavaScript,而且有助于我们了解编程语言的设计思路,拓宽我们的视野。 首先,...
### 理解Javascript原型继承原理 #### 一、引言 在JavaScript中,原型继承是一种非常核心且独特的机制,它使得对象能够继承其他对象的属性和方法。本文旨在深入探讨这一机制,并通过具体的示例代码帮助读者更好地...
JavaScript是一种广泛应用于Web开发的动态编程语言,尤其以其强大的面向对象特性而闻名。面向对象编程(Object-Oriented ...通过阅读`prototype.js`这样的示例代码,可以帮助加深对JavaScript面向对象编程的理解。
在深入讲解JavaScript面向对象与原型的知识点之前,首先需要了解JavaScript的基础知识。在JavaScript中,面向对象编程(OOP)的概念虽然存在,但是它的实现与传统基于类的语言有所不同。ECMAScript,也就是...
本文将深入探讨JavaScript中的原型、原型对象以及原型链的概念,并通过具体示例帮助读者更好地理解和应用。 #### 原型与原型对象 在JavaScript中,每个函数都有一个特殊的属性`prototype`,这是一个指针,指向一个...
在JavaScript中,面向对象编程基于原型,这使得它与其他面向对象语言(如Java或C++)有所不同。以下是对JavaScript面向对象和原型机制的详细解释: 1. 面向对象的基本概念: - 类:在许多面向对象语言中,类是创建...
这两个概念是语言的核心部分,对于深入理解对象的属性查找机制、继承等方面有着不可替代的作用。 #### 原型(Prototype) 在JavaScript中,每个函数都有一个`prototype`属性,这个属性指向一个对象。当我们创建一...
JavaScript原型通用验证框架是一种基于JavaScript设计模式的高效验证工具,其核心原理是利用JavaScript的原型(prototype)特性来实现对象的扩展与复用,从而达到代码的模块化和可维护性。这一框架广泛应用于Web开发...
在JavaScript中,一切皆对象。然而,我们可以将这些对象分为两类:普通对象和函数对象。普通对象是通过字面量或构造函数创建的实例,例如使用对象字面量方式创建的o1、使用new Object()创建的o2、以及使用new构造...
### JS原型的个人理解 #### 引言 在JavaScript中,原型(Prototype)是一个非常核心的概念,它决定了对象之间的继承关系以及属性查找机制。本文将深入探讨JS原型的基本原理、实现方式及其应用,并通过具体示例帮助...
JavaScript是Web开发中不可或缺的一部分,尤其在前端领域,它的强大在于动态性和灵活性。在这个"基于js原型链的小游戏"中,我们...这不仅是一个理解JavaScript原型链的好例子,也是实践前端开发技能的绝佳实践项目。
JavaScript中的原型和原型链是理解面向对象编程的关键概念。万物皆对象,JavaScript中对象分为两类:普通对象(Object)和函数对象(Function)。函数对象包括通过`new Function`创建的函数,如`f1`, `f2`, `f3`,而...