了解JavaScript 面向对象基础 & 原型与对象
面向对象语言中的对象
老是能听到什么基于对象, 面向对象. 什么是对象, 如果有面向对象基础的人可以无视了, 下面举个简单的例子给大家讲讲面向对象中, 对象的定义, 这个是比较通用的, 不过对于JS来说不太一样, 但是理解总是好的.
首先, 先有类型(Class), 这个类是指具有本质相同的一类事物, 比如大自然中的, 动物类, 植物类, 岩石类, 他们在根本上面具有本质相同的特性, 类下面也区分小的类, 比如同是动物类, 动物类里面也可以有猫类, 狗类, 当然啦, 人类也是一种类, 而在编程中, 类就是这一类东西用代码体现的一种抽象.
然后, 就有了对象(Object), 对象就是类中的一个个体, 比如人类中的一个人, 这就是对象, 再举些例子, 比如猫类中一只猫, 狗类里面具体到个体的一只狗, 都可以理解为对象, 在编程中, 对象就是类抽象出来的一个个体的实例.
可能上面说的有点晦涩, 但是久了就好理解了, 现在举点更具体的例子, 老师这一个职业, 算是一类人, 也就是类, 而你最喜欢的那个老师就是这个类的对象, 说白了就是类有种包含关系, 人类里面可以有男人类, 女人类, 也可以有教师类, 消防员类, 在日后的学习中, 大家也会知道, 这些小的类都可以称之为人类的子类, 也可以说这些类继承了人类, 而对象却不具备这种特性, 它只是某个类抽象到个体之后的单个实例(也就是实际的例子), 比如一位老师, 一个消防员, 这都是对象.
JS中的对象
JS中对对象的描述也差不太多, 只是JS是一种基于对象的语言, 并不是完全意义上的面向对象, 想要实现JS的类, 应该是一种使用函数模拟的方式, 所以可以这么说, JS中有模拟的类, 不存在真实意义上的类. 不过我们这里不纠结类, 着重讲对象.
上面说的让大家对对象也有一定理解了, 那么下面给大家再加一个新的概念, 那就是属性, 属性是一个对象的一些特点, 比如拿人作为一个对象, 那么人就有名字, 年龄, 身高, 体重这些特点, 这些特点也就是这个人作为一个对象的属性. 所以现在我们知道了, 一个对象它是具有很多属性的.
那么概念性的东西差不多了, 现在我们开始着重用代码讲对象.
首先我们先创建出一个对象.
var person = {
name : "Jianwei",
age : 23,
gender : "male"
};
var peron大家都知道, 变量的声明, 指向了一个对象, 对象的类型如上所示, {}中间用" : "分隔的属性和属性值, 通常我个人习惯称之为键值对(key-value), 这里面创建了一个对象, 这个对象共有三个属性, name, age, gender, 属性名, 也就是key, 这个key的类型没有特殊的限制(可以是值, 可以是字符串, 甚至于可以是另一个对象), 但是会通过toString()方法自动转化为字符串, 所以可以理解为key最后都会是一个字符串, 而value的类型没有特殊的限定(可以是值, 可以是字符串, 对象等等). 要注意的是, 属性是无序的, 所以声明的时候不需要注意顺序之类的.
对象创建方法
第一种, 使用{}包含键值对的方式创建对象(对象直接量).
var person = {
name : "Jianwei",
age : 23,
gender : "male"
profession : {
compang : "Oricle",
job : "iOS"
}
};
第二种, 使用new构造器关键字.
var person = new Object();
第三种, 使用Object.create()方法创建对象.
var person = Object.create({
name : "Jianwei",
age : 23,
gender : "male"
});
前两个方式比较好理解, 最后的这种方式, 简单介绍下, Object.create这个方法需要一个对象类型的参数, 创造出的对象的原型指向的就是这个参数, 这个参数是字面量对象, 原型指向的自然是Object.prototype了, 具体使用哪个, 要因地制宜.
对象属性的访问
对象的属性一般通过两种方式访问, 最常见的是通过点方法来进行访问, 也可以通过key索引的方式, 如上的代码案例.
var person = {
name : "Jianwei",
age : 23,
gender : "male"
};
如果我想要为oerson的name属性重新赋值, 那么使用如下语句的实现效果是相同的.
person.name = "Jianwei Wang";
person["name"] = "Jianwei Wang";
对象的原型(prototype)
这里我还是用不严谨的个人理解来给大家讲, 这样有助于大家理解, 当大家能够理解我的看法, 再去查看严谨的理论, 我相信这样的学习是更好令人消化的.
之前我们有讲父类和子类, 就比如人类, 和教师类, 人类是教师类的父类(super class), 教师类是人类的子类, 所以人类具有的所有属性, 教师类都继承了下来, 比如姓名, 年纪, 教师类也可以有自己新的, 父类所没有的属性, 比如教过了多少学生, 带过多少班级. 所以现在大家先给自己一个这样的思想, 就是父类的不作特殊修饰的属性, 子类都可以继承.
现在我们再来看JS中的对象, 首先, 有两种创建对象的方式, 上面说过了, 继承也简单的解释了, 那么很恶心的知识下面是, 建议大家用一天的时间来理解.
每个JS对象(null除外, 其实它本来自己有一个类型的, 但是官方那边修改之后发现, 大量的浏览器都出错了, 所以当使用typeof的时候, null显示的类型还是Object类型), 都和另一个对象相关联, "另一个"对象就是原型.
通过直接量创建的对象都继承自Object.prototype(这句代码其实是对原型对象的引用).
var person = {
name : "Jianwei",
age : 23,
gender : "male"
};
那么这个person对象继承的就是Object.prototype, 如果这时候为其添加了一个属性, 语句如下:
Object.prototype.hobby = "eat";
那么这个时候, 也能够从person上面访问到hobby这个属性, 也可以对hobby进行修改(能否修改会取决于一些条件, 我这段代码是允许, 后面会讲具体的设置方法).
通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性的值.
function person(){
name : "Jianwei",
age : 23,
gender : "male"
};
var jianweiWang = new person();
那么这个jianweiWang对象继承的就是person.prototype, 如果这时候为其添加了一个属性, 语句如下:
person.prototype.hobby = "eat";
那么这个时候, 也能够从jianweiWang上面访问到hobby这个属性, 也可以对hobby进行修改(能否修改会取决于一些条件, 我这段代码是允许, 后面会讲具体的设置方法).
这个继承关系也可以称之为原型链, jianweiWang继承的是person.prototype, 再往上继承的是Object.prototype, 所以如果Object.prototype上的属性, 几乎所有的对象都会有.
所以假如为一个对象的一个属性赋值, 首先会顺着原型链向上找, 如果整个原型链都没有, 才会为这个对象添加一个属性.
所有的继承来的属性并不是实际拥有了, 只是通过原型链获取到了, 复制给了自己一份, 所以假如上面的例子.
jianweiWang.hobby = "run";
但是这个时候打印person.prototype.hobby, 结果还是"eat", 因为只是副本变了, 本身并不会变.