【JavaScript】对象
No1:
typeof
操作符获取对象的类型
null
的类型是object
,Array
的类型也是object
,如果我们用typeof
将无法区分出null
、Array
和通常意义上的object——{}
。
No2:
【包装对象】
包装对象用new
创建
var n = new Number(123); // 123,生成了新的包装类型 var b = new Boolean(true); // true,生成了新的包装类型 var s = new String('str'); // 'str',生成了新的包装类型
虽然包装对象看上去和原来的值一模一样,显示出来也是一模一样,但他们的类型已经变为object
typeof new Number(123); // 'object' new Number(123) === 123; // false typeof new Boolean(true); // 'object' new Boolean(true) === true; // false typeof new String('str'); // 'object' new String('str') === 'str'; // false
下面是没new的情况
var n = Number('123'); // 123,相当于parseInt()或parseFloat() typeof n; // 'number' var b = Boolean('true'); // true typeof b; // 'boolean' var b2 = Boolean('false'); // true! 'false'字符串转换结果为true!因为它是非空字符串! var b3 = Boolean(''); // false var s = String(123.45); // '123.45' typeof s; // 'string'
No3:
几条规则需要遵守:
-
不要使用
new Number()
、new Boolean()
、new String()
创建包装对象; -
用
parseInt()
或parseFloat()
来转换任意类型到number
; -
用
String()
来转换任意类型到string
,或者直接调用某个对象的toString()
方法; -
通常不必把任意类型转换为
boolean
再判断,因为可以直接写if (myVar) {...}
; -
typeof
操作符可以判断出number
、boolean
、string
、function
和undefined
; -
判断
Array
要使用Array.isArray(arr)
; -
判断
null
请使用myVar === null
; -
判断某个全局变量是否存在用
typeof window.myVar === 'undefined'
; -
函数内部判断某个变量是否存在用
typeof myVar === 'undefined'
。
No4:
number
对象调用toString()
123..toString(); // '123', 注意是两个点! (123).toString(); // '123'
这都尼玛什么鬼!
No5:
创建时间
var d = new Date(2015, 5, 19, 20, 15, 30, 123); d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST)
JavaScript的月份范围用整数表示是0~11,0
表示一月,1
表示二月……,所以要表示6月,我们传入的是5
!这绝对是JavaScript的设计者当时脑抽了一下,但是现在要修复已经不可能了。砍人的心都有了
var d = new Date(1435146562875); d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST) d.getMonth(); // 5
No6:
【RegExp】就是正则表达式
var re1 = /ABC\-001/; var re2 = new RegExp('ABC\\-001'); re1; // /ABC\-001/ re2; // /ABC\-001/
var re = /^\d{3}\-\d{3,8}$/; re.test('010-12345'); // true re.test('010-1234x'); // false re.test('010 12345'); // false
【切分字符串】
'a b c'.split(/\s+/); // ['a', 'b', 'c'] 'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd'] 'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
【分组】
var re = /^(\d{3})-(\d{3,8})$/; re.exec('010-12345'); // ['010-12345', '010', '12345'] re.exec('010 12345'); // null
【贪婪匹配】
var re = /^(\d+)(0*)$/; re.exec('102300'); // ['102300', '102300', '']
非贪婪匹配
var re = /^(\d+?)(0*)$/; re.exec('102300'); // ['102300', '1023', '00']
【全局匹配】--结尾+g
var s = 'JavaScript, VBScript, JScript and ECMAScript'; var re=/[a-zA-Z]+Script/g; // 使用全局匹配: re.exec(s); // ['JavaScript'] re.lastIndex; // 10 re.exec(s); // ['VBScript'] re.lastIndex; // 20 re.exec(s); // ['JScript'] re.lastIndex; // 29 re.exec(s); // ['ECMAScript'] re.lastIndex; // 44 re.exec(s); // null,直到结束仍没有匹配到
No7:
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\"W3C\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
var s = JSON.stringify(xiaoming);//或者JSON.stringify(xiaoming, null, ' ');
console.log(s);
运行结果
{ "name":"小明", "age":14, "gender":true, "height":1.65, "grade":null, "middle-school":""W3C" Middle School", "skills":[ "JavaScript", "Java", "Python", "Lisp" ] }
如果是
JSON.stringify(xiaoming, ['name', 'skills'], ' ');
运行结果
{ "name": "小明", "skills": [ "JavaScript", "Java", "Python", "Lisp" ] }
No8:
【序列化】
var xiaoming = { name: '小明', age: 14, gender: true, height: 1.65, grade: null, 'middle-school': '\"W3C\" Middle School', skills: ['JavaScript', 'Java', 'Python', 'Lisp'], toJSON: function () { return { // 只输出name和age,并且改变了key: 'Name': this.name, 'Age': this.age }; } }; JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'
JSON.parse()
把它变成一个JavaScript对象
JSON.parse('[1,2,3,true]'); // [1, 2, 3, true] JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14} JSON.parse('true'); // true JSON.parse('123.45'); // 123.45
No9:
【prototype】原型(类似通过继承来创建对象)
/ 原型对象: var Student = { name: 'Robot', height: 1.2, run: function () { console.log(this.name + ' is running...'); } }; function createStudent(name) { // 基于Student原型创建一个新对象: var s = Object.create(Student); // 初始化新对象: s.name = name; return s; } var xiaoming = createStudent('小明'); xiaoming.run(); // 小明 is running... xiaoming.__proto__ === Student; // true
JavaScript对每个创建的对象都会设置一个原型,指向它的原型对象。
No10:
原型链
var arr = [1, 2, 3];
其原型链是arr ----> Array.prototype ----> Object.prototype ----> null
Array.prototype
定义了indexOf()
、shift()
等方法,因此你可以在所有的Array
对象上直接调用这些方法。
function foo() { return 0; }
其原型链是foo ----> Function.prototype ----> Object.prototype ----> null
Function.prototype
定义了apply()
等方法,因此,所有函数都可以调用apply()
方法。
No11:
【构造函数】
function Student(name) { this.name = name; this.hello = function () { alert('Hello, ' + this.name + '!'); } }
var xiaoming = new Student('小明'); xiaoming.name; // '小明' xiaoming.hello(); // Hello, 小明!
xiaoming
的原型链是xiaoming ----> Student.prototype ----> Object.prototype ----> null
No12:
【原型继承】
// PrimaryStudent构造函数: function PrimaryStudent(props) { Student.call(this, props); this.grade = props.grade || 1; } // 空函数F: function F() { } // 把F的原型指向Student.prototype: F.prototype = Student.prototype; // 把PrimaryStudent的原型指向一个新的F对象,F对象的原型正好指向Student.prototype: PrimaryStudent.prototype = new F(); // 把PrimaryStudent原型的构造函数修复为PrimaryStudent: PrimaryStudent.prototype.constructor = PrimaryStudent; // 继续在PrimaryStudent原型(就是new F()对象)上定义方法: PrimaryStudent.prototype.getGrade = function () { return this.grade; }; // 创建xiaoming: var xiaoming = new PrimaryStudent({ name: '小明', grade: 2 }); xiaoming.name; // '小明' xiaoming.grade; // 2 // 验证原型: xiaoming.__proto__ === PrimaryStudent.prototype; // true xiaoming.__proto__.__proto__ === Student.prototype; // true // 验证继承关系: xiaoming instanceof PrimaryStudent; // true xiaoming instanceof Student; // true
JavaScript的原型继承实现方式就是:
-
定义新的构造函数,并在内部用
call()
调用希望“继承”的构造函数,并绑定this
; -
借助中间函数
F
实现原型链继承,最好通过封装的inherits
函数完成; -
继续在新的构造函数的原型上定义新方法
No13:
【class继承】
class Student { constructor(name) { this.name = name; } hello() { alert('Hello, ' + this.name + '!'); } } var xiaoming = new Student('小明'); xiaoming.hello();
看到这,我觉得之前的原型链啥还是不要学的好!
【class继承】
class PrimaryStudent extends Student { constructor(name, grade) { super(name); // 记得用super调用父类的构造方法! this.grade = grade; } myGrade() { alert('I am at grade ' + this.grade); } }
终于和java的语法统一了,js太多坑爹的语法,希望早日移除