ECMAScript is an object-oriented programming language supporting delegating inheritance based on prototypes.
ECMAScript是一种面向对象语言,支持基于原型的委托式继承。
var a = undefined;
var b = null;
var c = true;
var d = 'test';
var e = 10;
alert(typeof null); // "object"
Object is an unordered collection of key-value pairs.
对象是一个包含key-value对的无序集合
var x = { // 对象"x"有3个属性: a, b, c
a: 10, // 原始值
b: {z: 100}, // 对象"b"有一个属性z
c: function () { // 函数(方法)
alert('method x.c');
}
};
alert(x.a); // 10
alert(x.b); // [object Object]
alert(x.b.z); // 100
x.c(); // 'method x.c'
var foo = {x: 10};
// 添加新属性
foo.y = 20;
console.log(foo); // {x: 10, y: 20}
// 将属性值修改为函数
foo.x = function () {
console.log('foo.x');
};
foo.x(); // 'foo.x'
// 删除属性
delete foo.x;
console.log(foo); // {y: 20}
var foo = {x: 10};
// 冻结对象
Object.freeze(foo);
console.log(Object.isFrozen(foo)); // true
// 不能修改
foo.x = 100;
// 不能扩展
foo.y = 200;
// 不能删除
delete foo.x;
console.log(foo); // {x: 10}
var foo = {x : 10};
Object.defineProperty(foo, "y", {
value: 20,
writable: false, // 只读
configurable: false // 不可配置
});
// 不能修改
foo.y = 200;
// 不能删除
delete foo.y; // false
// 防治扩展
Object.preventExtensions(foo);
console.log(Object.isExtensible(foo)); // false
// 不能添加新属性
foo.z = 30;
console.log(foo); {x: 10, y: 20}
var c = new Boolean(true);
var d = new String('test');
var e = new Number(10);
// 转换成原始值
// 使用不带new关键字的函数
с = Boolean(c);
d = String(d);
e = Number(e);
// 重新转换成对象
с = Object(c);
d = Object(d);
e = Object(e);
// 等价于new Array(1, 2, 3);
// 或者array = new Array();
// array[0] = 1;
// array[1] = 2;
// array[2] = 3;
var array = [1, 2, 3];
// 等价于
// var object = new Object();
// object.a = 1;
// object.b = 2;
// object.c = 3;
var object = {a: 1, b: 2, c: 3};
// 等价于new RegExp("^\\d+$", "g")
var re = /^\d+$/g;
var getClass = Object.prototype.toString;
Object = Number;
var foo = new Object;
alert([foo, getClass.call(foo)]); // 0, "[object Number]"
var bar = {};
// Rhino, SpiderMonkey 1.7中 - 0, "[object Number]"
// 其它: still "[object Object]", "[object Object]"
alert([bar, getClass.call(bar)]);
// Array也是一样的效果
Array = Number;
foo = new Array;
alert([foo, getClass.call(foo)]); // 0, "[object Number]"
bar = [];
// Rhino, SpiderMonkey 1.7中 - 0, "[object Number]"
// 其它: still "", "[object Object]"
alert([bar, getClass.call(bar)]);
// 但对RegExp,字面量的语义是不被改变的。 semantics of the literal
// isn't being changed in all tested implementations
RegExp = Number;
foo = new RegExp;
alert([foo, getClass.call(foo)]); // 0, "[object Number]"
bar = /(?!)/g;
alert([bar, getClass.call(bar)]); // /(?!)/g, "[object RegExp]"
for (var k = 0; k < 4; k++) {
var re = /ecma/g;
alert(re.lastIndex); // 0, 4, 0, 4
alert(re.test("ecmascript")); // true, false, true, false
}
// 对比
for (var k = 0; k < 4; k++) {
var re = new RegExp("ecma", "g");
alert(re.lastIndex); // 0, 0, 0, 0
alert(re.test("ecmascript")); // true, true, true, true
}
var a = {x: 10};
a['y'] = 20;
a.z = 30;
var b = new Number(1);
b.x = 10;
b.y = 20;
b['z'] = 30;
var c = new Function('');
c.x = 10;
c.y = 20;
c['z'] = 30;
// 等等,任意对象的子类型"subtype"
Object.prototype.x = 10;
var a = {}; // 创建空"hash"
alert(a["x"]); // 10, 但不为空
alert(a.toString); // function
a["y"] = 20; // 添加新的键值对到 "hash"
alert(a["y"]); // 20
Object.prototype.y = 20; // 添加原型属性
delete a["y"]; // 删除
alert(a["y"]); // 但这里key和value依然有值 – 20
var aHashTable = Object.create(null);
console.log(aHashTable.toString); // 未定义
var a = new String("foo");
a['length'] = 10;
alert(a['length']); // 3
a = {}
a.class # Hash
a.length # 0
# new "key-value" pair
a['length'] = 10;
# 语义上,用点访问的是属性或方法,而不是key
a.length # 1
# 而索引器访问访问的是hash里的key
a['length'] # 10
# 就类似于在现有对象上动态声明Hash类
# 然后声明新属性或方法
class Hash
def z
100
end
end
# 新属性可以访问
a.z # 100
# 但不是"key"
a['z'] # nil
var a = new Number(1);
var primitiveA = Number(a); // 隐式"valueOf"调用
var alsoPrimitiveA = a.valueOf(); // 显式调用
alert([
typeof a, // "object"
typeof primitiveA, // "number"
typeof alsoPrimitiveA // "number"
]);
var a = new Number(1);
var b = new Number(2);
alert(a + b); // 3
// 甚至
var c = {
x: 10,
y: 20,
valueOf: function () {
return this.x + this.y;
}
};
var d = {
x: 30,
y: 40,
// 和c的valueOf功能一样
valueOf: c.valueOf
};
alert(c + d); // 100
var a = {};
alert(a.valueOf() === a); // true, "valueOf"返回this
var d = new Date();
alert(d.valueOf()); // time
alert(d.valueOf() === d.getTime()); // true
var a = {
valueOf: function () {
return 100;
},
toString: function () {
return '__test';
}
};
// 这个操作里,toString方法自动调用
alert(a); // "__test"
// 但是这里,调用的却是valueOf()方法
alert(a + 10); // 110
// 但,一旦valueOf删除以后
// toString又可以自动调用了
delete a.valueOf;
alert(a + 10); // "_test10"
var n = Object(1); // [object Number]
var s = Object('test'); // [object String]
// 一些类似,使用new操作符也可以
var b = new Object(true); // [object Boolean]
// 应用参数new Object的话创建的是简单对象
var o = new Object(); // [object Object]
// 如果参数是一个现有的对象
// 那创建的结果就是简单返回该对象
var a = [];
alert(a === new Object(a)); // true
alert(a === Object(a)); // true
var a = Array(1, 2, 3); // [object Array]
var b = new Array(1, 2, 3); // [object Array]
var c = [1, 2, 3]; // [object Array]
var d = Function(''); // [object Function]
var e = new Function(''); // [object Function]
var a = 1;
var b = 2;
// 隐式
var c = a + b; // 3, number
var d = a + b + '5' // "35", string
// 显式
var e = '10'; // "10", string
var f = +e; // 10, number
var g = parseInt(e, 10); // 10, number
// 等等
var foo = {};
Object.defineProperty(foo, "x", {
value: 10,
writable: true, // 即{ReadOnly} = false
enumerable: false, // 即{DontEnum} = true
configurable: true // 即{DontDelete} = false
});
console.log(foo.x); // 10
// 通过descriptor获取特性集attributes
var desc = Object.getOwnPropertyDescriptor(foo, "x");
console.log(desc.enumerable); // false
console.log(desc.writable); // true
// 等等
var getClass = Object.prototype.toString;
getClass.call({}); // [object Object]
getClass.call([]); // [object Array]
getClass.call(new Number(1)); // [object Number]
// 等等
// in IE - "String", in other - "Function"
alert(getClass.call(document.childNodes.item));