完整教程:9.4 面向对象
什么是对象
我们一直在用对象 可是你真的理解对象吗,js中有一个说法是一切皆对象,其实这里说的应该是一切皆可看作对象
对象就是可以拥有属性和方法的一个集合
士兵就是一个对象,它拥有身高体重的属性,保家卫国,吃饭睡觉的动作方法
在座的各位都是对象,世界上的万物都可看作对象,所以说,编程世界多姿多彩
什么是面向对象
面向过程:面向过程专注于如何去解决一个问题的过程步骤,是由一个个函数去实现每一步的过程步骤,没有类和对象的概念
面向对象:专注于由哪一个对象来解决这个问题,编程特点是出现了一个类,从类中拿到对象,由这个对象去解决具体问题
对于调用者来说,面向过程需要调用者自己去实现各种函数。而面向对象,只需要告诉调用者,对象中具体方法的功能,而不需要调用者了解方法中的实现细节。 面向对象的三大特征:
封装
继承
多态
需要理解的概念
属性:对象本身所拥有的
方法:对象能够做的事情【功能】
抽象:在所有的丢像中获取相同的特征的过程
封装:创建对象的过程
继承:从一个对象中获取另外一个对象的内容【属性方法】
重写:继承父级的方法之后,又对方法进行修改
创建对象的方式
- 字面量的方式
var car = { // 车对象
// 属性
color:'白色',
width: '2000mm',
height: '1500mm',
brand:'BMW',
price:'56W',
// 方法
run: function(){
console.log( this.brand + '在路上行驶');
},
stop: function(msg){
console.log(this.brand + '刹不住车了!' + msg);
}
};
// 调用对象的属性
console.log(car.color);
// 调用对象的方法
car.run('hello');
car.stop('hello');
- Object的方式
var car = new Object();
// 属性
car.width = '1500mm';
car.color = '白色';
car.brand = 'BMW';
// 方法
car.stop = function(){
console.log(this.brand + '刹不住车了!');
}
car.run = function(){
console.log( this.brand + '在路上行驶');
}
console.log(car.color);
car.run();
- 在已经存在的对象上添加属性和方法
var arr = new Array();
// 给数组添加num属性
arr.num = 10;
// 给数组添加getNum方法
arr.getNum = function(){
console.log(arr.num);
}
arr.getNum();
构造对象
什么是构造对象
当通过 new
关键字调用一个函数时,这个函数就可以称为构造函数
构造对象和函数的区别
调用方式不同 普通函数只用
函数名
调用 构造函数通过 new 关键字 调用返回值不同 普通函数的返回值是函数体内 return 的结果 构造函数的返回值是 new 关键字 生成的对象
原型对象
所有函数
都有一个原型对象 prototype,并且只有函数
才拥有原型对象 prototype。 原型对象也是一个对象
原型对象和构造对象
原型对象 prototype
所有函数
都有一个原型对象 prototype,并且只有函数
才拥有原型对象 prototype。 原型对象也是一个对象
构造函数 constructor
函数的原型对象的构造函数 是这个函数自己。也就是
Object.prototype.constructor === Object;// true
![[d080f46b-60ea-4ca4-acbd-738db668b45b.png]]
实例化对象
假如通过new 关键字从
函数fun
里创建的对象obj
,可以把 obj 称为 fun 的实例化对象;通过字面量方式创建的对象可以称为
Object
的实例化对象;实例化对象和普通对象没有任何区别
proto
每个对象都拥有一个属性 proto
,这是浏览器实现的属性,通过它可以访问到 构造函数constructor 上的 原型对象 prototype;
var obj = new Object();
obj.
__proto__
=== obj.constructor.prototype;// true
obj.__proto__ === Object.prototype;// true
![[8b281bc1-5bb4-4fdc-ab5e-075901ed8fe6.png]]
new 关键字 创建对象时发生了什么
当使用 new
关键字从 Object
函数上新建一个对象 obj
时, new
关键字会进行如下的操作: 总结:new一个实例话对象经历的四个阶段:
创建一个空的实例话对象
让构造函数中的this指向空的实例话对象
执行(调用)构造函数,从而创建实例话对象自身的属性和方法
返回实例化对象
总结:创建对象的方法
用构造方式添加属性
用 new 关键字调用 不需要用 return 显式返回值的,默认会返回 this,也就是新的实例对象。 建议函数名的首字母大写,与普通函数区分开。用原型方式添加方法
构造函数
创建构造函数
function creatObj(width,color,brand,lang){
// 属性 - 构造属性
this.width = width; // this
this.color = color;
this.brand = brand;
this.lang = lang;
// 方法 - 构造方法
this.run = function(){
console.log( this.brand + '在路上行驶');
}
this.start = function(){
console.log( this.brand + 'start');
}
this.stop = function(){
console.log(this.brand + '刹不住车了!');
}
}
var byd = new creatObj('1500mm','red','比亚迪');
var bmw = new creatObj('1500mm','白色','BMW');
bmw.start();
byd.start();
这样也可以创建一个对象,但是每次创建的对象的地址都是一个新的内存地址,内存地址是不同的
console.log(bmw.start == byd.start); // false
这样会更加浪费内存空间,需要讲方法放在原型中
// 构造函数;
function creatObj(width,color,brand,lang){ // 类
// 属性 - 构造属性
this.width = width; // this
this.color = color;
this.brand = brand;
this.lang = lang;
// 方法 - 构造方法
this.run = function(){
console.log( this.brand + '在路上行驶');
}
}
// 原型 prototype - 属性
creatObj.prototype.lang = this.lang;
// 原型 prototype - 方法
creatObj.prototype.start = function(){
console.log( this.brand + 'start');
}
creatObj.prototype.stop = function(){
console.log(this.brand + '刹不住车了!');
}
var byd = new creatObj('1500mm','red','比亚迪'); // 对象
var bmw = new creatObj('1500mm','白色','BMW'); // 对象
bmw.start();
byd.start();
案例:给数组添加sum求和方法
正常添加
var arr = new Array(1,2,3,4,5,6,7);
// sum 字定义了一个方法
arr.sum = function(){
var res = 0;
for(var i=0; i
当前sum方法只是添加给了arr这个对象,并没有添加给整个数组对象,所以如果是给已经存在的对象添加方法,需要使用prototype原型方法
var arr = new Array(1,2,3,4,5,6,7);
// sum 字定义了一个方法
Array.prototype.sum = function(){
var res = 0;
for(var i=0; i
原型相关的方法
Object.getPrototypeOf() 取得实例的原型对象。 Object.getPrototypeOf(person1);
isPrototypeOf() 判断是不是一个实例的原型对象。 Person.prototype.isPrototypeOf(person1);
hasOwnProperty() 检测一个属性是否存在于实例中 person1.hasOwnProperty(“name”);
in 判断一个属性是否存在于实例和原型中。 “name” in person1;
面向对象就是一种全新的写法而已。用面向过程能实现的功能,面向对象依然能够实现,对于初学者来说优点麻烦
思考:给数组添加去重方法
方法一:函数方式实现
function arrayNoRepeat(arr) {
var tempArr = [];
for (var i = 0; i < arr.length; i++) {
if (tempArr.indexOf(arr[i]) == -1) {
tempArr.push(arr[i]);
}
}
return tempArr;
}
var numArr = [9, 9, 3, 4, 8, 9, 3, 4, 8];
var relArr = arrayNoRepeat(numArr);
console.log(numArr);
console.log(relArr);
方法二:通过原型方法实现
Array.prototype.noRepeat = function () {
for (var i = 0; i < this.length; i++) {
for (var j = i + 1; j < this.length; j++) {
if (this[j] == this[i]) {
this.splice(j, 1);
j--;
}
}
}
}
console.log(numArr);
numArr.noRepeat();
console.log(numArr);