深入理解 Javascript 之 对象

2018-08-09 admin

图例


先谈谈 ECMAScript 中的数据类型

ES6 之前 ECMAScript 中有 5 种简单数据类型(也称为【基本数据类型】):UndefinedNullBooleanNumberString

还有一种复杂的【引用数据类型】Object

ES6引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型。它也是基本数据类型。

基本数据类型的值是按值访问的
基本类型的值是不可变的
基本类型的比较是它们的值的比较
基本类型的变量是存放在栈内存(Stack)里的

引用类型的值是按引用访问的
引用类型的值是可变的
引用类型的比较是引用的比较
引用类型的值是保存在堆内存(Heap)中的对象(Object) 与其他编程语言不同,JavaScript 不能直接操作对象的内存空间(堆内存)

图解:


检测变量类型

typeof

适合判断基本数据类型和function的判断

typeof "sss" ===> "string"
typeof 123 ===> "Number"
typeof [1,2,3] ===> "object"
typeof new Date() ===> "object"
typeof function(){alert('111');}  ===> "function"
typeof undefined ===> "undefined"
typeof NaN ===> "number"
typeof null ===> "object"

instanceof

判断已知的对象类型或者是自定义的对象

  • 目标对象 + instanceof + 函数构造器[可以理解为是某个对象是否是某个构造器的实例]
  • 原理: 判断左边的对象的原型链上是否有右侧的构造函数的prototype属性
[1,3] instanceof Array === true
new Array('1, 3,4') instanceof Array === true
new Object() instanceof Object === true
new String("string") instanceof String === true
function(){this.name="22";} instanceof Function === true

// 定义一个构造函数
function Person(){

}
// 定义一个构造函数
function Student(){

}
// 每一个构造函数都有一个prototype对象属性, 这个对象属性将会作为通过new Person()创建的对象的一个原型。
// 也就是当我们在new 一个对象的时候,这个对象的原型就指向了这个构造函数的prototype。

Student.prototype = new Person(); // student继承至person

var bson = new Student();
bson instanceof Student
// false

bson instanceof Person
// true

Object.prototype.toString.apply()

判断基本数据类型和内置对象

Object.prototype.toString.apply([]) === "[object Array]"
Object.prototype.toString.apply(function(){}) === "[object Function]"

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]"
Object.prototype.toString.apply(124)
// "[object Number]"
Object.prototype.toString.apply("222")
// "[object String]"
Object.prototype.toString.apply(true)
// "[object Boolean]"
Object.prototype.toString.apply(null)
// "[object Null]"
Object.prototype.toString.apply(null) === "[object Null]"   // 在IE6/7/8下存在有兼容性问题

创建对象

使用 Object 构造函数创建

// 对象实例的创建
var obj = new Object() 
obj.key = 'value'   //使用构造函数创建一个空对象,并赋值

使用对象字面量表示法创建

//使用字面量创建一个对象
var obj = {
    key1: 'value1',
    key2: 'value2'
}  

ES6中还有更简洁的

var age = 20
var sex = "sexy"

var a = {
    name: 'jack',

    // 简洁表示法,等同于 age: age
    age, 

    // 简洁表示法,等同于 sayName: function() {}
    sayName(){}, 

    // 属性名表达式,等同于 lover: 'rose'
    ['lo' + 'ver']: 'rose', 

    // 属性名表达式,等同于 sexy: 'male'
    [sex]: 'male'
}

工厂模式[创建多个相似的对象]

var createPerson (name, age){
    var o = {};
    o.name = name;
    o.age = age;
    o.sayName = function(){
        console.log(this);
    }
    return o;
}

var a = createPerson ('zjj', 20);
var b = createPerson ('zmf', 30);

工厂模式虽然解决多创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。


模仿“类”的设计

构造函数模式

function Person (name, age) {
    this.name = name;
    thia.age = age;
    this.sayName = function() { alert(this.age) }
}
Person.prototype.count = 2;
var a = new Person('a', 20)
var b = new Person('b', 22)

a instanceof Person // true
  • 构造函数与其他函数唯一的区别就在于调用他们的方式不同。任何函数只要通过new 操作符来调用,那它就可以作为构造函数。

使用new操作符调用函数

function CO(){  
    this.p = “I’m in constructed object”;  
    this.alertP = function(){  
        alert(this.p);  
    }  
}  

var o2 = new CO();  

var obj = {}; // 第一步创建一个空对象
obj.__proto__ = CO.prototype; // 该对象的原型链指向构造函数的 prototype 所指向的对象。
CO.call(obj); // 第三步,将构造函数的作用域赋值给新的对象
return obj; // 返回新的对象

上面这种构造函数解决了对象类型识别的问题,但是每个方法都要在每个实例上重新创建一遍,在上面的例子中,a 和 b 都有个名为sayName()的方法,这两个方法虽然名字、内容、功能相同,但却分别在 a 和 b 中都重新创建了一次,这是没有必要的。

更好的方法应该是将公用的方法放到他们的原型上,也就是接下来要说的原型模式。

原型模式

所有函数都有一个不可枚举的 prototype(原型)属性,这个属性是一个指针,指向一个对象。

Person.prototype

返回如下:

clipboard.png

原文链接:https://segmentfault.com/a/1190000015949901

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-37645.html

文章标题:深入理解 Javascript 之 对象

相关文章
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
javascript是什么意思
avaScript是Netscape开发的一个对象脚本语言,它使用在世界各地数以百万计的网页和服务器应用程序上。 网景的JavaScript是ecma - 262版的标准脚本语言,和公布的标准只有轻微的差异。 与广为流行的错误理解相反,Ja...
2015-11-12
21天学通javascript
简介: 本书是Javascript入门教程。Javascript是Web开发中应用最早、发展最成熟、用户最多的脚本语言。其语法简洁,代码可读性在众多脚本语言中最好,它在使用时不用考虑数据类型,是真正意义上的动态语言。本书总分为四篇,共21章...
2015-11-16
JavaScript的组成
一个完整的JavaScript由3个部分组成:核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模型(BOM) ECMAScript 描述了该语言的语法和基本对象 ; DOM 描述了处理网页内容的方法和接口 ; BOM 描...
2015-11-12
JavaScript 事件流、事件处理程序及事件对象总结
JS与HTML之间的交互通过事件实现。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用监听器(或处理程序)来预定事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察员模式,支持页面的行为与页面的外观之间的松散耦合。...
2017-04-05
JavaScript变量的声明
声明变量 变量在脚本中的首次亮相是在其声明中。 在变量首次出现时将会在内存中设置它,因此您稍后可在脚本中引用它。 应在使用变量之前先声明变量。 可以使用 var 关键字实现此目的。 <span id=“mt9” class=“sent...
2015-11-12
jQuery中DOM树操作之使用反向插入方法实例分析
本文实例讲述了jQuery中DOM树操作之使用反向插入方法。分享给大家供大家参考。具体分析如下: 使用反向插入方法 这里我们先把创建的内容插人到元素前面,然后再把同一个元素插人到文档 中的另一个位置。通常,当在jQuery中操作元素时,利用...
2015-11-13
7个提高效率的JavaScript调试工具
鐜板湪鐨凧avaScript浜嬪疄涓婂凡鐒舵垚涓轰簡娴佽�岀殑web璇�瑷€锛屽嵆浣垮畠骞朵笉瀹岀編銆傚緢澶氱▼搴忓憳涓嶅枩娆㈢敤JavaScript鍐欎唬鐮侊紝鏄�鍥犱负鍐欏埌鍚庢潵鎬讳細鍑虹幇鍚勭�嶈帿鍚嶅叾濡欑殑bug锛岃€屼笖鍦ㄥ紑...
2015-11-11
7个让JavaScript变得更好的注意事项
随着浏览器性能提高,伴随着新的HTML5的编程接口的稳步采用,网页上的JavaScript的音量在逐渐增加。然而,一个写得不好的程序编码却拥有着打破整个网站,让用户为之沮丧和驱赶潜在客户的潜力。 开发人员必须使用所有供他们任意使用的工具和技...
2015-11-12
JavaScript短路原理精简代码
js中||和&&的特性帮我们精简了代码的同时,也带来了代码可读性的降低,虽然高效,但请灵活使用。 在js逻辑运算中,0、""、null、false、undefined、NaN都会判为false,其他都为t...
2015-11-12
回到顶部