JavaScript数据类型

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

一、用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种基本类型:


image.png


点击查看在线代码


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对象的一切成员。

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


image.png


点击查看在线代码


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)特权方法与特权属性


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

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

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

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


image.png


点击查看在线代码


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)继承


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


image.png


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版新特性...


相关文章
|
3月前
|
存储 JavaScript 对象存储
js检测数据类型有那些方法
js检测数据类型有那些方法
145 59
|
11天前
|
存储 JavaScript 前端开发
JavaScript中的数据类型以及存储上的差别
通过本文的介绍,希望您能够深入理解JavaScript中的数据类型及其存储差别,并在实际编程中灵活运用这些知识,以提高代码的性能和稳定性。
40 3
|
1月前
|
存储 JavaScript 前端开发
js中的数据类型
JavaScript 中的数据类型包括五种基本类型(String、Number、Undefined、Boolean、Null)和三种引用类型(Object、Array、Function,以及ES6新增的Symbol)。基本类型直接存储值,引用类型存储的是指向实际数据的内存地址。了解它们的区别对于掌握 JavaScript 的变量赋值和函数传参至关重要。
24 1
|
2月前
|
存储 JavaScript 前端开发
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
JavaScript 数据类型分为基本数据类型和引用数据类型。基本数据类型(如 string、number 等)具有不可变性,按值访问,存储在栈内存中。引用数据类型(如 Object、Array 等)存储在堆内存中,按引用访问,值是可变的。本文深入探讨了这两种数据类型的特性、存储方式、以及检测数据类型的两种常用方法——typeof 和 instanceof,帮助开发者更好地理解 JavaScript 内存模型和类型检测机制。
116 0
JavaScript 数据类型详解:基本类型与引用类型的区别及其检测方法
|
2月前
|
JavaScript 前端开发 开发者
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
【干货拿走】JavaScript中最全的数据类型判断方法!!!!
29 1
|
2月前
|
存储 JavaScript 前端开发
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
52 0
|
3月前
|
JavaScript 前端开发
JavaScript基础知识-基本数据类型和引用数据类型
关于JavaScript基础知识的文章,主要介绍了基本数据类型和引用数据类型。
46 2
JavaScript基础知识-基本数据类型和引用数据类型
|
3月前
|
存储 前端开发 JavaScript
前端基础(三)_JavaScript数据类型(基本数据类型、复杂数据类型)
本文详细介绍了JavaScript中的数据类型,包括基本数据类型(Number、String、Boolean、Undefined、Null)和复杂数据类型(Object),并解释了如何使用`typeof`操作符来识别变量的数据类型。同时,还讨论了对象、函数和数组等复杂数据类型的使用方式。
72 2
|
4月前
|
JavaScript 前端开发
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
这篇文章是JavaScript基础与实战教程的第一部分,涵盖了JavaScript的基本语法、标识符、数据类型以及如何进行强制类型转换,通过代码示例介绍了JS的输出语句、编写位置和数据类型转换方法。
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
|
4月前
|
开发者 图形学 开发工具
Unity编辑器神级扩展攻略:从批量操作到定制Inspector界面,手把手教你编写高效开发工具,解锁编辑器隐藏潜能
【8月更文挑战第31天】Unity是一款强大的游戏开发引擎,支持多平台发布与高度可定制的编辑器环境。通过自定义编辑器工具,开发者能显著提升工作效率。本文介绍如何使用C#脚本扩展Unity编辑器功能,包括批量调整游戏对象位置、创建自定义Inspector界面及项目统计窗口等实用工具,并提供具体示例代码。理解并应用这些技巧,可大幅优化开发流程,提高生产力。
448 1