JavaScript数据类型

简介:

一、用toString判断类型

toString() 方法返回一个代表该对象的字符串。当对象需要转换为字符串时,会调用它的toString()方法。

默认情况下,每个对象都会从Object上继承到toString()方法,如果这个方法没有被这个对象自身或者更接近的上层原型上的同名方法覆盖(遮蔽),则调用该对象的toString()方法时会返回"[object type]",这里的字符串type表示了一个对象类型。点击查看在线代码

var toString = Object.prototype.toString;

function write_one(str) {
    document.writeln('<p>'+str+'</p>');
}
// [object Date]
write_one(toString.call(new Date));

// [object String]
write_one(toString.call(new String));

// [object Math]
write_one(toString.call(Math));

// [object Number]
write_one(toString.call(1));

// [object Boolean]
write_one(toString.call(true));

// [object Object]
write_one(toString.call(new Object()));

// [object Regexp]
write_one(toString.call(/\d/));

// [object Array]
write_one(toString.call([]));

// [object Function]
write_one(toString.call(write_one));

// [object Error]
write_one(toString.call(new Error()));

// [object Arguments]
function display_args() {
    write_one(toString.call(arguments));
};
display_args();

//Since JavaScript 1.8.5
// [object Undefined]
write_one(toString.call(undefined));

// [object Null]
write_one(toString.call(null));

开源的underscore库中的那几个isFunction、isString等方法就是用toString做的判断:

  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
    _['is' + name] = function(obj) {
      return toString.call(obj) === '[object ' + name + ']';
    };
  });

 

二、基本类型

《JavaScript语言精髓与编程实践》中提到有6种基本类型:

点击查看在线代码

write_one(typeof 1); //number
write_one(typeof 'xx'); //string
write_one(typeof true); //boolean
write_one(typeof undefined); //undefined
write_one(typeof null); //object
write_one(typeof function(){}); //function

 

三、对象

对象是JavaScript中的基本数据结构。JavaScript支持继承,即通过动态代理机制重用代码或数据。但不像许多传统的语言,JavaScript的继承机制基于原型,而不是类。

1)对象的类型

1.本地对象:

ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。包括如下:

Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError 

 

2.内置对象:

ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。

只定义了两个,GlobalMath

 

3.宿主对象:

ECMAScript中的“宿主”当然就是我们网页的运行环境,即“操作系统”和“浏览器”。所有的BOMDOM对象都是宿主对象。

 

2)早绑定和晚绑定

所谓绑定(binding),即把对象的接口与对象实例结合在一起的方法。

  早绑定(early binding)是指在实例化对象之前定义它的属性和方法,这样编译器或解释程序就能够提前转换机器代码。在 Java 和 Visual Basic 这样的语言中,有了早绑定,就可以在开发环境中使用 IntelliSense(即给开发者提供对象中属性和方法列表的功能)。ECMAScript 不是强类型语言,所以不支持早绑定。

  晚绑定(late binding)指的是编译器或解释程序在运行前,不知道对象的类型。使用晚绑定,无需检查对象的类型,只需检查对象是否支持属性和方法即可。ECMAScript 中的所有变量都采用晚绑定方法。这样就允许执行大量的对象操作,而无任何惩罚。

晚绑定示例如下,点击查看在线代码

var a=function(){};  
a.prototype.p1 = 1;  
var b = new a();
write_one(b.p1);//1 
write_one(b.p2);//undefined
a.prototype.p2=2;  
write_one(b.p2);//2
  1. b初始化a的一个实例,此时输出b.p1,根据prototype链接,结果是1
  2. 而第一次输出b.p2时,显示的 undefined
  3. 然后,再设置a.prototype.p2=2,此时在输出b.p2,显示的是2
  4. 所有这些就是prototype链在作怪

 

3)new操作符

JavaScript的所有函数都可以作为构造器。构造器与普通的方法没有什么区别。

prototype存在于每一个函数上,当new一个函数的时候,这个实例对象就拥有这个函数的prototype对象的一切成员。

从而实现共享一组方法或属性。这跟火影里的影分身应该差不多,分身也会螺旋丸技能,思维也是共通的等。

点击查看在线代码

function naruto1() {}
naruto1.prototype = {
    say: "never give up",
    SpiralPill: function() {}//螺旋丸
};
var a = new naruto1;
var b = new naruto1;
write_one(a.say === b.say);//true
write_one(a.SpiralPill === b.SpiralPill);//true

 

4)特权方法与特权属性

直接在构造器内指定其方法,叫特权方法,如果是属性就叫特权属性。每一个实例一个副本,各不影响。

  这就比如各个影分身的表情、动作等,可以各不相同的

特权属性和方法是会遮住原型方法或属性的。

  这就好比分身用了风车手里剑后就不能使用螺旋丸了。

点击查看在线代码

function naruto1() {
  this.say = "I want to become Naruto";
  this.SpiralPill = function() {
    return 'windmill hand sword';//风车手里剑
  }
  this.expression = function(){}
}
naruto1.prototype = {
    say: "never give up",
    SpiralPill: function() {}//螺旋丸
};
var a = new naruto1;
var b = new naruto1;
write_one(a.say === b.say);//true
write_one(a.SpiralPill === b.SpiralPill);//false
write_one(a.expression === b.expression);//false,引用类型每次进入函数体都重新创建,因此不一样

 

5)类方法与类属性

原型方法和特权方法都属于实例方法。类方法或属性可直接定义在函数上。

点击查看在线代码

naruto1.bag = function(){};
var c = new naruto1;
write_one(c.bag === undefined);//true

 

6)继承

鸣人的螺旋丸是从自来也那里学来的,后续他自己又开发了新的螺旋丸相关的忍术。

function Jiraiya(){}//自来也
Jiraiya.prototype = {
    SpiralPill: function() {}//螺旋丸
};

function bridge(){}//修行
bridge.prototype = Jiraiya.prototype;

function naruto2(){}
naruto2.prototype = new bridge();
naruto2.prototype.windmill = function(){
  //风车手里剑 独有
}

var a = new Jiraiya();
var b = new naruto2();

write_one(a.SpiralPill === b.SpiralPill);//true
write_one(Jiraiya.prototype === naruto2.prototype);//false
write_one(a.windmill === b.windmill);//false
write_one(b instanceof Jiraiya);//true
write_one(b instanceof naruto2);//true

 

7)__proto__

在标准浏览器和IE11中,可以访问__proto__属性。

var a = new naruto();

分解步骤:

  1. var a={}; 也就是说,初始化一个空对象a
  2. a.__proto__ = naruto.prototype
  3. 将构造器里的this=a
  4. 执行构造器里的代码

 

8)ECMA-262,第5版中将对象增强

1.Object.create():

使用一个指定的原型对象和一个额外的属性对象创建一个新对象。

2.Object.preventExtensions() :

阻止将任何新命名的特性添加到对象

3.Object.isExtensible():

测试命名特性是否可以添加到对象

4.Object.seal():

首先调用 Object.preventExtensions() ,阻止添加新特性,然后将所有对象特性的 configurable 标志设置为 false。这允许锁定对象的所有特性(但不锁定对象的值),使其可预测,以用作数据存储。循环一个密封的数据对象的值现在成为一个更加可预测的任务,特别是配合使用 enumerable 标志时。

5.Object.isSealed() :

测试对象是否可配置

6.Object.freeze():

调用 Object.seal() 来停止对象的配置, 然后将所有对象特性的 writeable 标志设置为 false,提供一个完美静态的对象。在有多个源与数据交互的环境中,完全冻结对象的能力能创建一种此前无法实现的可预测性和安全性级别。

7.Object.isFrozen() :

测试对象是否冻结

8.Object.getPrototypeOf() :

返回对象的原型。该方法的值等同于非标准的 Object.__proto__ 特性。

9.Object.keys() :

方法返回一个字符串数组,表示一个对象自己的可数(enumerable)特性的名称,这些特性是在 enumerable 标志设置为 true 的正在接受调查的对象上直接定义的特性。

10.Object.getOwnPropertyNames() :

与上述方法类似,但还包含 enumerable 标志设置为 false 的特性。

11.访问符(getters 和 setters):

Get 和 set 将一个对象特性绑定到一个函数,该函数将在试图访问或写入一个属性的值时被调用。Get 不接受参数;而 set 接受一个参数(要设置的值)。

点击查看更多ECMA-262第5版新特性...

 

 

参考资料:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString Object.prototype.toString()

http://www.ibm.com/developerworks/cn/web/wa-ecma262/ ECMA-262,第5版

http://www.w3school.com.cn/js/pro_js_object_working_with.asp ECMAScript 对象应用



    本文转自 咖啡机(K.F.J)   博客园博客,原文链接:http://www.cnblogs.com/strick/p/4524851.html,如需转载请自行联系原作者


相关文章
|
3月前
|
存储 JavaScript 对象存储
js检测数据类型有那些方法
js检测数据类型有那些方法
141 59
|
4月前
|
JavaScript 算法 前端开发
采招网JS逆向:基于AES解密网络数据
采招网JS逆向:基于AES解密网络数据
69 0
|
26天前
|
数据采集 存储 JavaScript
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
本文介绍了如何使用Puppeteer和Node.js爬取大学招生数据,并通过代理IP提升爬取的稳定性和效率。Puppeteer作为一个强大的Node.js库,能够模拟真实浏览器访问,支持JavaScript渲染,适合复杂的爬取任务。文章详细讲解了安装Puppeteer、配置代理IP、实现爬虫代码的步骤,并提供了代码示例。此外,还给出了注意事项和优化建议,帮助读者高效地抓取和分析招生数据。
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
|
2月前
|
前端开发 JavaScript
JS-数据筛选
JS-数据筛选
34 7
|
2月前
|
存储 JavaScript 前端开发
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
JavaScript 数据类型分为基本数据类型和引用数据类型。基本数据类型(如 string、number 等)具有不可变性,按值访问,存储在栈内存中。引用数据类型(如 Object、Array 等)存储在堆内存中,按引用访问,值是可变的。本文深入探讨了这两种数据类型的特性、存储方式、以及检测数据类型的两种常用方法——typeof 和 instanceof,帮助开发者更好地理解 JavaScript 内存模型和类型检测机制。
80 0
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
|
2月前
|
JavaScript 数据安全/隐私保护
2024了,你会使用原生js批量获取表单数据吗
2024了,你会使用原生js批量获取表单数据吗
50 4
|
2月前
|
JavaScript 前端开发 开发者
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
23 1
|
3月前
|
JavaScript 前端开发 安全
js逆向实战之烯牛数据请求参数加密和返回数据解密
【9月更文挑战第20天】在JavaScript逆向工程中,处理烯牛数据的请求参数加密和返回数据解密颇具挑战。本文详细分析了这一过程,包括网络请求监测、代码分析、加密算法推测及解密逻辑研究,并提供了实战步骤,如确定加密入口点、逆向分析算法及模拟加密解密过程。此外,还强调了法律合规性和安全性的重要性,帮助读者合法且安全地进行逆向工程。
95 11
|
2月前
|
存储 JavaScript 前端开发
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
19 0
|
3月前
|
存储 前端开发 JavaScript
前端基础(三)_JavaScript数据类型(基本数据类型、复杂数据类型)
本文详细介绍了JavaScript中的数据类型,包括基本数据类型(Number、String、Boolean、Undefined、Null)和复杂数据类型(Object),并解释了如何使用`typeof`操作符来识别变量的数据类型。同时,还讨论了对象、函数和数组等复杂数据类型的使用方式。
52 2