创建和操作
例如一个对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var mrPiao = { name : '票', age : 1, sex : 'male', health : 100, eat : function() { console.log('I am eating'); this.health --; }, drink : function() { console.log('I am drink'); this.health ++; } }
|
增删改查:
1 2 3 4
| mrPiao.toy = '逗猫棒'; delete mrPiao.sex; mrPiao.age = 2; console.log(mrPiao.health);
|
访问一个对象没有的属性时,会返回undefined。
创建对象目前有三种方法:
- 对象字面量,又叫对象直接量(Plain Object),直接写即可。如
var object = {} - 构造函数。构造函数又分为系统自带和自定义。
- Object.create(原型) 方法。
通过Object.create(原型)方法创建对象:
- 自己指定原型:
var tuan = {...} - 创建一个对象并将原型写入:
var piao = Object.creat(tuan) - 此时
piao就为一个对象,它的原型是tuan
1 2 3 4 5 6 7 8 9
| var tuan = { name : '团', age : 1 }
var piao = Object.create(tuan);
console.log(typeof(piao)); console.log(piao.__proto__);
|
构造函数
系统自带的构造函数
Object(); Array(); Number(); Boolean(); Date();
构造函数前面加一个new,就可以返回一个对象,然后通过变量接收即可。如:var obj = new Object();
构造函数创建的对象,和对象字面量创建的对象没有区别。构造函数就像一个工厂,每执行一次,就创建一个对象。每次创建的对象,一模一样但相互独立。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var num = new Number(123);
var str = new String('abcd');
var bol = new Boolean(true);
console.log(num); console.log(str); console.log(bol);
num.name = '豆'; console.log(num);
console.log(num * 2);
|
自定义构造函数
由于构造函数和函数在结构上没有任何区别,所以为了区分,构造函数命名需要严格遵守大驼峰式命名规则:从第一个单词开始首字母大写。
依然使用new操作符生成对象。
具体步骤:
- 创建一个构造函数,里面写共有属性。
- 通过
new返回一个对象,用变量接收。执行一次返回一个对象。 - 可以单独为这个对象增加属性,不影响返回的其他对象。
1 2 3 4 5 6 7 8 9 10 11 12
| function Person() { this.age = 3; }
var person = new Person(); var person1 = new Person();
person.name = '团';
console.log(person);
console.log(person1);
|
内部原理
没有new操作符的话,就按照函数正常执行。
有new操作符时,系统会执行如下三步:
- 在函数体最前面隐式的加上一个对象:
this = Object.create(构造函数.prototype) = {}; - 执行
this.xxx = xxx; - 隐式的返回 this:
return this;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function Student(name, age, sex) {
this.name = name; this.age = age; this.sex = sex; this.grade = 2019;
}
var student = new Student('团', 3, 'female');
console.log(student);
|
使用
在构造函数内可以增加属性,还可以设置参数:
1 2 3 4 5 6 7 8 9 10
| function Student(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.grade = 2019; }
var student = new Student('团', 3, 'female');
console.log(student);
|
如果对象的属性不存在,直接访问的话,会返回 “undefined”。
1 2 3 4 5 6 7 8
| function Person() { this.age = 3; } var obj = new Person(); console.log(obj); console.log(obj.name);
|
在构造函数过程中,如果强制显式的返回一个引用值,可以将隐式返回的this覆盖。
1 2 3 4 5 6 7 8 9 10 11
| function Person (name, height){ this.name = name; this.height = height; this.say = function () { console.log(this.say); } return {a: 'b'}; }
var person = new Person('王', 180); console.log(person);
|
但如果是强制显式返回原始值,那么就无法覆盖,依然输出隐式的this。
1 2 3 4 5 6 7 8 9 10 11
| function Person (name, height){ this.name = name; this.height = height; this.say = function () { console.log(this.say); } return 123; }
var person = new Person('王', 180); console.log(person);
|
包装类
前提
只有对象才有属性和方法,原始值不能有。
数字 number 包含原始值数字和数字对象。
1 2 3
| var num = 123; num.name = '数字'; console.log(num.name);
|
- 数字对象
new Number(...)可以有属性和方法,且可以参与运算。不过运算完成后,它会变成原始值数字。
1 2 3 4 5 6 7 8 9 10 11 12 13
|
var num = new Number(123);
num.name = '数字';
console.log(num);
console.log(typeof num);
console.log(num * 2);
console.log(typeof( num * 2));
|
字符串 string 包含原始值字符串和字符串对象。
1 2 3
| var str = 'abcd'; str.name = '字符串'; console.log(str.name);
|
- 字符串对象
new String(...)可以有属性和方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var str = new String('abcd');
str.name = '字符串'; str.sayValue = function () { return this.name; }
console.log(str);
console.log(typeof str);
var result = str.sayValue();
console.log(result);
|
布尔 boolean 同上。
1 2 3 4 5
| var bol = new Boolean(true);
bol.name = '布尔';
console.log(bol);
|
null 和 undefined 只有原始值,它们不会经过包装类,也就不会有对象,进而不会有原型,而对象的最终原型里的toString()方法也就无法使用。
1 2 3
| null.name = '空';
undefined.name = '未定义';
|
原始值与包装类
原始值不能有属性和方法,但是往原始值上面加了属性后没有报错,是因为经历了包装类的过程:
- 第一步:原始值调用属性
num.len = 3;,系统隐式地自动新增一个数字对象并赋值:new Number(num).len = 3;,紧接着将它删除:delete。 - 第二步:当你访问
num.len这个属性时,系统又重新建立一个数字对象:new Number(num).len给你访问。 - 结果:访问一个对象没有的属性时,会输出
undefined。
1 2 3 4 5 6 7 8
|
var num = 4;
num.len = 3;
console.log(num.len);
|
经历过包装类后,不会报错,但最后结果一定是undefined。
例题
例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
var arr = [1, 2, 3, 4, 5]; arr.length = 2; console.log(arr);
var str = 'abcd'; str.length = 2;
console.log(str);
console.log(str.length);
|
综合考察:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| function Person(name, age, sex){ var a = 0; this.name = name; this.age = age; this.sex = sex; function sss() { a ++; console.log(a); } this.say = sss; }
var oPerson = new Person(); oPerson.say(); oPerson.say();
var oPerson1 = new Person(); oPerson1.say();
|