由浅入深学习JavaScript对象
1.创建对象
(1)使用字面量语法创建对象
var obj= {
name:"Arvin",
lastName:"Huang" , //变量
engine: {cylinders: 4, size: 2.2}, //数组
whatsName:function(){
alert(this.name+" "+this.lastName);
}, //方法
}
由上面的代码我们可以看出实际上在JS中的对象就是一个以键值对形式存储属性的一个集合,每一个属性有一个特定的名称,并与名称相对应的值。
(2)使用构造函数语法创建对象
new关键字和对象的构造函数相结合可创建一个空白对象,随后可以为其添加属性和方法。
var obj = new Object();
obj.name = 'lyl';
console.log(obj.name); //lyl
此外,我们还可以自定义构造函数,例如:
function Obj (name) {
this.name = name;
this.age = 18;
}
var obj = new Obj('lyl');
console.log(obj.name); //lyl
console.log(obj.age); //18
自定义构造函数的基本构造原理:
我们首先看一个样例,
function Obj () {
this.age = 18;
}
// 不用new
console.log(Obj()); // undefined
// 用new
console.log(new Obj()); //Obj {age: 18}
其实一切的关键全在与new这个操作符上,用new和不用new返回的结果大相径庭。不用new,则Obj(‘lyl’)根本就是一个函数的正常执行,没有返回值,则默认返回undefined,而是用new操作符后js引擎就会将该函数看作构造函数看待,经过内部的一系列隐式操作,返回值就是一个对象了。
用new返回值为对象的基本原理:
首先看样例:
// 构造函数的原型
Person.prototype = {
say: function () {
console.log('I am saying');
}
}
// 构造函数
function Person () {
// 隐式操作
// var this = Object.create(Person.prototype);
//返回对象属性的设置
this.name = 'lyl';
this.age = 18;
// 隐式操作
// return this;
}
var person1 = new Person();
console.log(person1.name); // lyl
person1.say(); //I am saying
不用new,函数内的this指向的是window,所以this.xxx定义的变量都是window上的属性,但为什么使用new后其中的this就不是window对象了呢?
那是因为用new后,js引擎会在函数被进行两步隐式操作(假设构造函数名为Person):第一步, var this = Object.create(Peson.prototype); (也是创建对象的一种方法,下边会讲到) 隐士的改变函数内this的含义,现在函数内的this是一个原型为Person.prototype, 构造函数为Person的对象(其实此过程就将想要的对象基本创造成功了,只是差些属性而已,从此可是看出构造函数创建对象的最根本原理是借用Object.create()方法来实现的,只不过被封装功能化了); 第二步, 在创建的对象设置完所需要的属性后,隐式的将创建的对象this通过return返回 return this;
上述两步理论的验证:
(1)第一步:现在函数内的this是一个原型为Person.prototype, 构造函数为Person的对象
// 构造函数的原型
Person.prototype = {
say: function () {
console.log('I am saying');
}
}
// 构造函数
function Person () {
this.name = 'lyl';
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
(2)第二步:隐式的将创建的对象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
(3)使用Object.create()方法创建对象
var obj = Object.create({x:1,y:2});//obj继承了属性x和y
这一方法传入的参数是一个对象,并且这一作用的对象将会作为新的对象的原型存在。
2.对象的增、删、改、查
(1)增
所谓增添一个对象的属性,就是直接对该属性进行赋值操作即可,这就相当于为该对象添加了一个新属性,而打印未添加的属性,浏览器不会报错,而是会打印出undefined。
var obj = {};
console.log(obj.name); //undefined (不会报错)
obj.name = 'lyl';
console.log(obj.name); // lyl
(2)删
我们通过delete操作符来删除一个对象的属性
var obj = {
name : 'lyl'
};
console.log(obj.name); //lyl
delete obj.name;
console.log(obj.name); //undefined
(3)改
直接通过赋值操作赋予其其他的值即可
var obj = {
name: 'lyl'
};
console.log(obj.name); // lyl
obj.name = 'obj';
console.log(obj.name); // obj
(4)查
查询一个对象的属性值有两种方法
var obj = {
name: 'lyl'
};
// 第一种方法
console.log(obj['name']); //lyl
// 第二种方法
console.log(obj.name); // lyl
//p.s.最本质的是第一种方法,因为在使用第二种方法时,后台自动将其转换为第一种字符串的形式来查询
3.原型
(1)原型的定义: 原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过改构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
(2)利用原型特点和概念,可以提取共有属性。将一类对象的共有属性提取出来,放到该类对象的原型中,从而不需要每次用new操作符时都重新定义一遍该共有属性。
如下,定义一个Person构造函数,而属于Person多构造对象共有的属性方法,则定义到Person的原型中。
Person.prototype = {
eat: function (food) {
console.log('I have eated ' + food);
},
sleep: function () {
console.log("I am sleeping");
}
}
// 人的构造函数
function Person (name, age) {
this.name = name;
this.age = age;
}
var person1 = new Person('lyl', 18);
console.log(person1.name); //lyl
person1.eat('apple'); //I have eated apple
4.内置对象
(1)Array对象:
属性:
.length 获得数组的长度;
方法:
.concat() 连接内容或者数组,组成新的数组;
.join(n) 用n连接数组的每一项组成字符串,可以是空字符串;
.pop() 删除数组的最后一项数据,并返回删除的数据;
.push() 在数组最后加入新的内容返回新的数组的长度
.reverse() 翻转数组;
(2)String对象
属性:
.length 获取字符串的长度。
方法:
.charAt(n) 找到位置在n(索引)上的字符。
.charCodeAt(n) 找到索引位置上的字符的编码:a=97,A=65。
.indexOf(“m”) 查找字符m在字符串中第一次出现的索引;如果没有找到返回-1。
.lastIndexOf(“m”) 查找字符m在字符串中最后一次出现的索引;如果没有找到返回-。
.split(“n”) 以字符n分割字符串,并返回一个数组,空字符串时分割每个字符,如果字符串中没有该字符,同样返回数组。
.substr(n,m) 截取字符串,从索引是n的位置开始截取,截取m个字符;如果只有一个参数n,那就是从n开始截取,截取到最后。
.substring(n,m) 截取字符串,从索引是n的位置开始截取,截取到第m个字符(m娶不到);如果只有一个参数n,那就是从n开始截取,截取到最后。
.toLowerCase() 把字符串中的字母转化成小写。
.toUpperCase() 把字符串中的字母转化成大写。
(3)Math对象
方法:
Math.pow(n,m) n的m次方。
Math.abs(n) n到原点的距离(n的绝对值)。
Math.round(n) 四舍五入取整。
Math.floor(n) 地板函数(向下取整)。
Math.ceil(n) 天花板函数 (向上取整)。
Math.random() 返回0-1的随机数(取不到1)。
(4)Date对象 var date = new Date();
方法:
.toLocaleString() 以当前本地格式显示时间。
date.getFullYear() 获取date对象的年份。
date.getMonth() 获取月份(0-11)对应1-12月。
date.getDate() 获取日期。
date.getHours() 获取小时。
date.getMinutes() 获取分钟
date.getSeconds() 获取多少秒
date.getMilliSeconds() 毫秒数
date.getDay() 获取星期几(0-6) 对应 周天至周六。
date.getTime() 从1970年开始到时间日期的毫秒值(时间戳)
date.setFullYear 设置年份
此外,还有其他许多内置对象,这里不再一一列举。