JavaScript中并非一切皆对象
对象是js中的基础以及核心,在js中有六种主要类型:string number boolean null undefined object
除了oject类型以为其他五种本身并非对象,null本身被划为object类型本身是js中的一个bug,即使它的typeof类型是 object,实际上null本身还是基本类型。
常见的错误说法是:js中万物皆是对象,这显然是错误的。
实际上,js中有许多特殊的对象子类型。我们称之为复杂基本类型。
js中有一些对象子类型被称为内置对象,如:
• String
• Number
• Boolean
• Object
• Function
• Array
• Date
• RegExp
• Error
原理是这样的,不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判 断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“object”。
在 JavaScript 中,它们实际上只是一些内置函数。这些内置函数可以当作构造函数来使用,从而可以构造一个对应子类型的新对象。举例来说:
var strPrimitive = "I am a string"; typeof strPrimitive; // "string" strPrimitive instanceof String; // false var strObject = new String( "I am a string" ); typeof strObject; // "object" strObject instanceof String; // true // 检查 sub-type 对象
Object.prototype.toString.call( strObject ); // [object String]
数组也是对象,所以虽然每个下标都是整数,你仍然可以给数组添加属性:
var myArray = [ "foo", 42, "bar" ];
myArray.baz = "baz";
myArray.length; // 3
myArray.baz; // "baz"
可以看到虽然添加了命名属性,数组的 length 值并未发 生变化。
如果你试图向数组添加一个属性,但是属性名“看起来”像一个数字,那它会变成 一个数值下标(因此会修改数组的内容而不是添加一个属性):
var myArray = [ "foo", 42, "bar" ];
myArray["3"] = "baz";
myArray.length; // 4
myArray[3]; // "baz"
接着有必要介绍行对象的三个属性:writable(可写)、 enumerable(可枚举)和 configurable(可配置)。
var myObject = {};
Object.defineProperty( myObject, "a", {
value: 2,
writable: true,
configurable: true,
enumerable: true
} )
writable 决定是否可以修改属性的值。
configurable 禁止修改以及删除属性。delete也不好使。
enumerable 决定对象的属性是否可以被枚举,如for in
Object.seal(..) 会创建一个“密封”的对象,这个方法实际上会在一个现有对象上调用 Object.preventExtensions(..) 并把所有现有属性标记为 configurable:false。
Object.freeze(..) 会创建一个冻结对象,这个方法实际上会在一个现有对象上调用 Object.seal(..) 并把所有“数据访问”属性标记为 writable:false,这样就无法修改它们 的值。
对象的defineproperty以及set,get,在vue等框架中是核心原理。这里就不展开说了,所以vue只能兼容到IE8,因为必须的得支持对象的es5对象中的一系列方法才行。
对于上面提到的for in 可以联想到for of,还有重要的iterator数组的迭代器。如何手动调试循环 next()启动,以及返回值是什么,看下面的例子。
var myObject = {
a: 2,
b: 3
};
Object.defineProperty( myObject, Symbol.iterator, {
enumerable: false,
writable: false,
configurable: true,
value: function() { var o = this;
var idx = 0;
var ks = Object.keys( o );
return {
next: function() {
return {
value: o[ks[idx++]],
done: (idx > ks.length)
};
} };
}
} );
// 手动遍历 myObject
var it = myObject[Symbol.iterator]();
it.next(); // { value:2, done:false }
it.next(); // { value:3, done:false }
it.next(); // { value:undefined, done:true }
// 用 for..of 遍历 myObject
for (var v of myObject) {
console.log( v );
}
// 2
// 3
调用迭代器的 next() 方法会返回形式为 { value: .. , done: .. } 的值, value 是当前的遍历值,done 是一个布尔值,表示是否还有可以遍历的值。
最后的调用一次 next() 才能得到 done:true,从而确定完成遍历。
和数组不同,普通的对象没有内置的 @@iterator,所以无法自动完成 for..of 遍历。之所 以要这样做,有许多非常复杂的原因,不过简单来说,这样做是为了避免影响未来的对象 类型。
for..of 循环每次调用 myObject 迭代器对象的 next() 方法时,内部的指针都会向前移动并 返回对象属性列表的下一个值(再次提醒,需要注意遍历对象属性 / 值时的顺序)。
JavaScript中并非一切皆对象的更多相关文章
- javascript中遇到的字符串对象处理
在javascript中对参数处理: 1 <script> 2 function getParam() 3 { 4 urlInfo=window.location.href; //获取当前 ...
- javascript中的内置对象
2015.12.1 javascript中的内置对象 复习: 1.js中的内置函数 alert prompt write parseInt parseFloat eval isNaN document ...
- (转载)JavaScript中的Window窗口对象
(转载)http://www.ijavascript.cn/jiaocheng/javascript-window-65.html 例子: <html> <head> < ...
- javaScript中Math内置对象基本方法入门
概念 Math 是javaScript的内置对象,包含了部分数学常数属性和数学函数方法. Math 不是一个函数对象,用户Number类型进行使用,不支持BigInt. Math 的所有属性与方法都是 ...
- JavaScript“并非”一切皆对象
上一篇:<函数声明和函数表达式--函数声明和函数表达式的异同> p{font-size:14px; } 写在前面 网上非常多都在说"JavaScript一切皆对象",那 ...
- 深入理解Javascript中构造函数和原型对象的区别
在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ...
- JavaScript中的原型和对象机制
1.对象相关的一些语言特性 JavaScript里所有的东西都是对象, 对象是属性的集合.要知道,函数也是对象, 能够作为变量的值. 返回值. 参数或者属性的值. 函数对象特殊的地方是能通过" ...
- 谈谈javascript中的日期Date对象
一.日期对象 在javascript中并没有日期型的数据类型,但是提供了一个日期对象可以操作日期和时间. 日期对象的创建: new Date();二.将日期对象转换为字符串 将日期对象转换为字 ...
- 了解 JavaScript 中的内置对象
所有编程语言都具有内部(或内置的)对象来创建 语言的基本功能.内部对象是 您编写自定义代码所用语言的基础, 该代码基于您的想象实现自定义功能.JavaScript 有许多 将其定义为语言的内部对象.本 ...
随机推荐
- 在rails 中使用mysql 出现Mysql::Error: Incorrect string value: 的问题
这是因为你在做数据库的操作中有非英文的问题,之后gem mysql2 处理中文必须要数据库也指定是utf-8 才比较好处理 解决的方法很简单,将数据库每张表都转化成utf-8即可,如果数据库没有什么重 ...
- pat1043. Is It a Binary Search Tree (25)
1043. Is It a Binary Search Tree (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN ...
- ASP.NET操作DataTable各种方法
转:http://www.cnblogs.com/isking/p/6178268.html http://www.cnblogs.com/sntetwt/p/3496477.html public ...
- 使用@Cacheable 踩过的坑
public class XXX{ @Resourceprivate XXX self;//@Cacheable通过内部调用将不会使用缓存,从Spring4.3开始可以通过注入self,再通过self ...
- Socket网络通信之NIO
Socket网络通信之NIO NIO:new io ,java1.4开始推出的可非阻塞IO. java.nio 包,可解决BIO阻塞的不足 但比BIO学习.使用复杂. 可以以阻塞.非阻塞两种方式工作. ...
- select标签使用 三目运算符
<td> <select id="roleName" name="roleName" class="input" styl ...
- sass文件转css时注释虽然支持中文,但是出现乱码的解决方法
sass文件转css时注释虽然支持中文,但是出现乱码的解决方法 Scss 注释中文报错问题(windows系统, 已解决)找到ruby的安装目录,里面也有sass模块,类似这样样的路径:F:\Prog ...
- oracle多表查询和子查询练习
--1.列出至少有三个员工的所有部门和部门信息. SELECT D.DEPTNO, D.DNAME, D.LOC, T.COUNTS FROM DEPT D, (SELECT DEPTNO, CO ...
- Inconsistent accessibility
Inconsistent accessibility: return type 'ConsoleApplication17.IBacklight' is less accessible than me ...
- Shader笔记
1,渲染队列值小的先渲染,值大的后渲染 2,zTest,zWrite zTest:LEqua zWrite:On 则:zWrite中,深度值小于深度值缓冲区的值会被通过 参考:http://www.c ...