写一个对象的例子吧。
function Person(name, age) { this.name = name; this.age = age; this.family = ['gg', 'jj']; } Person.prototype = { constructor : Person, // Person.prototype = (),覆盖了过去的,所有要重新指向。 sayTell : function () { alert(this.name + " " + this.age + " " + this.family.join(' ') + " ..."); } }; var people1 = new Person('hg', 22); people1.family.push('bb'); var people2 = new Person('wj', 23); people2.family.push('mm'); people1.sayTell(); people2.sayTell(); // 组合继承模式 function Student(name, age, sex, grade) { this.sex = sex; this.grade = grade; Person.call(this, name, age); // 让Student的对象,调用Person的方法。 } Student.prototype = new Person(); // 改变prototype的指向 Student.prototype.sayAll = function () { alert(this.name + " " + this.age + " " + this.grade); } stu1 = new Student('hg', 22, 'nan', 7); stu2 = new Student('og', 24, 'nv', 9); stu1.sayAll(); stu2.sayAll();
对象类型。
(1)浏览器扩展对象,不同的浏览器厂商,有自己的对象。不通用。带来了兼容性
W3C和ES标准
(2)宿主对象
window,document,navigator.浏览器运行环境提供的。
naigator:包含浏览器信息。
(3)原生对象
构造函数:function, Array, Date,RegExp,Error, String,Number,Object,Boolean。
对象: Math, JSON, 全局对象, arguments。
原始类型和对象类型的区别
构造函数的变量,都是在栈内存中,直接用变量标识符就可以找到。
还有当声明object对象时,var obj = new Object();
obj对象的指针存在栈内存中,做指向。而对象本身在堆中。
举例:
var num1 = 123; //在栈内存中申请了一个内存空间,给了num1
var num2 = num1; //在栈内存中又申请了,一个变量内存。num2。
var obj1 = {a:1};
var obj2 = obj1;
这里obj1和obj2,都指向{a:1}; 如果更改obj2.a = 2;那么obj1.a同时也改变了。
//如果想真实的复制一个对象。使用深拷贝。
var a = { a:1, b:2, c:{a:1, b:2}}; function cloneAll(obj){ function Clone() { } Clone.prototype = obj; var o = new Clone(); for (var a in o) { if (typeof o[a] == "object") { o[a] = cloneAll(o[a]); } } return o; } var b = cloneAll(a); alert(b.c.a);
JS隐式类型转换。
var bbb = 3.141593;
bbb.toFixed(2);
bbb -> 3.14
字符串和数字之间的转换。
if语句中的转换。
==运算符
类型识别
一, typeof 是个操作符,不是一个方法,可以识别出标准类型,除了null
(1)typeof null == 'object'
(2)typeof [], new Date, /d/, 都是object
(3)typeof function == function.
二, instanceof
[] instanceof Array; //true
/d/ instanceof RegExp; //true
(1)instanceof 可以判定内置类型,但是不能判定原始类型。
(2)可以识别自定义类型。
function Point(x, y) { this.x = x; this.y = y; } function Circle(x, y, r) { Point.call(this, x, y); this.radius = r; } Circle.prototype = new Point() Circle.prototype.constructor = Circle; var c = new Circle(1, 1, 2); c instanceof Circle; //true c instanceof Point; //true
三, Object.prototype.toString.call
call借用了这个方法。借用函数。 Object.prototype.toString.call('123'); //[object String] Object.prototype.toString.call(123); //"[object Number]" //封装成一个方法。 function type(obj) { return Object.prototype.toString.call(obj).slice(8, -1); } type([123,32]); Object.prototype.toString.call() (1)可以识别标准类型以及内置(build-in)对象类型。 如果是自定义的方法,比如 function Point(x, y) { this.x = x; this.y = y; } type(new Point(1,2)); //object类型 (2)不能识别自定义的对象类型。
四, constructor
生成这个对象的构造函数的本身。使用构造函数来判断对象类型,肯定是准确的
alert('string'.constructor === String); //true alert((1).constructor === Number); //true true.constructor === Boolean; //true ({}).constructor === Object; //true (1)undefined, null不能判断,因为他们没有构造函数。 (2)判断内置对象类型 [].constructor === Array; //true new Date().constructor === Date; //true (3)也可以判定自定义的对象类型。 function Person(name) { this.name = name; } new Person('hg').constructor === Person; //true //获取对象构造函数名称 function getConstructorName(obj) { return obj && obj.constructor && obj.constructor.toString().match(/functions*([^(]*)/)[1]; } obj.constructor.toString() //将构造函数转换为字符串。 .match(/functions*([^(]*)/)[1]; //这里在把字符串匹配出来。 function Person(name) { this.name = name; } getConstructorName(new Person('hg')); //Person
//获取对象构造函数名称
function getConstructorName(obj) {
return obj && obj.constructor && obj.constructor.toString().match(/functions*([^(]*)/)[1];
}
这个方法,很酷,可以获取任何类型的构造函数的返回值,来判断参数类型。