js 之 对象(一)
其实,在现实生活中,对象是一个个体的组合,一件事物,例如电脑,汽车,轮船等待。
而这是单个能够行动,运转的个体是由无数个零件组成。电脑由显示器,键盘,鼠标,耳机等等设备,飞机由机身,起降设备,发动机,机翼等组成。
同样的,在js 世界,对象是一系列 属性 和 值的集合。
即 对象是JavaScript的一个基本数据类型,是一种复合值,它将很多值(原始值或者其他对象)聚合在一起,可通过名字访问这些值。即属性的无序集合。
二、对象的创建(多种方法)
1、对象直接量 / 字面量
var obj = {
name: 'pp',
age: 18
}
console.log(obj.name); // pp
2、构造函数:
(1)、系统自带的的, eg: new Object(), Array(), Number(),Boolean(), Date()…
var obj = new Object();
obj.name = 'pp';
console.log(obj.name); // pp
(2)、自定义的:为了和普通函数区分,首字母大写,采用大驼峰式写法(普通函数采用小驼峰式写法)
function Obj (name) {
this.name = name;
this.age = 18;
}
var obj = new Obj('pp');
console.log(obj.name); //pp
console.log(obj.age); //18
自定义构造函数的基本构造原理:
首先,文字理论解释一番,其实一切的关键全在与new这个操作符上,用new和不用new返回的结果大相径庭。不用new,则Obj(‘pp’)根本就是一个函数的正常执行,没有返回值,则默认返回undefined,而是用new操作符后js引擎就会将该函数看作构造函数看待,经过内部的一系列隐士操作,返回值就是一个对象了。
看下如下demo:
demo1:用new和不用new的区别演示:
// 构造函数的原型
Person.prototype = {
say: function () {
console.log('I am saying');
}
}
// 构造函数
function Person () {
this.name = 'pp';
this.age = 18;
// 打印this对象的原型
console.log(this.__proto__); //
// 验证this是否是Person构造函数的实例
console.log(this instanceof Person); //true
}
new Person();//打印结果如下
// Object say: ()__proto__: Object
// true
Person();//打印结果如下
// Window
// false
第二步:隐式的将创建的对象this通过return返回
由以上一些代码,我们已经可以看出返回的是满足条件的对象,现在我们创建对象时不用new,并显示的模拟这两步隐式操作来验证(我们不用new则两步隐式操作就不会产生)
// 构造函数的原型
Person.prototype = {
say: function () {
console.log('I am saying');
}
}
// 构造函数
function Person () {
var that = Object.create(Person.prototype);
that.name = 'lyl';
that.age = 18;
return that;
//提前返回that导致return this无法执行而失效
}
var person = new Person();
//此处不用new也是可以成功返回一个满足条件的对象,因为显示的返回了that
console.log(person.name); //lyl
person.say(); //I am saying
p.s. 关于显示返回that的问题,当我们用new生成对象,若我们显示return的是一个对象 / 引用值,则会导致return this失效,若返回的是原始值,则return this不会失效
3、Object.create(原型); 创建一个继承该原型的实例对象
关于此方法的一些注意事项:
(1)、若传参为Object.prototype,则创建的原型为Object.prototype,和 new Object()创建的对象是一样的 Object.create(Object.prototype) <==>new Object();
(2)、若传参为空 或者 null,则创建的对象是没有原型的, 导致该对象是无法用document.write()打印会报错,因为document.write()打印的原理是调用Object.prototype.toString()方法,该对象没有原型,也就没有该方法,所以document.write()无法打印
由此延伸的知识点: 引用值都也是算作是对象,所以都可以用document.write()打印;原始值numebr, boolean, string都有自己对象的包装类,借助此机制也是可以用document.write()打印出的;
但undefined 和 null既不是引用值,也没有对应的包装类,所以应该无法打印的,但大家会发现这两个值也是可是用document.write()打印的,因为这两个值被设定为特殊值,document.write()打印其是不用调用任何方法的,而是之直接打印其值