什么是面向对象?
面向对象程序设计,英语全称 Object Oriented Programming,简称OOP。这里的Object,中文翻译成对象,实际上就是指东西;
面向对象就是相对于面向过程来说的,面向过程就是分析出解决问题的步骤,然后一步一步的去实现它;面向对象就是用对象的方式和方法来解决问题,把问题看做一个一个的对象,基于对象去解决;
面向对象的特征?
面向对象具有三大特征:
1、封装:内部运作隐藏起来,把使用的基本功能展现给用户,就好像电视机的遥控器。
2、继承:新对象继承现有对象的特征,在基础上再增加一些新的特性
3、多态:行为相同,但是可以用于不同的物体,物体不同,最后的结果也就不同。
原型方法
1、prototype和”proto”
prototype和proto效果是一样的,都是可以找到自己的原型对象:
let arr = [1,2,3,4,5];
console.log(Array.prototype);[]
console.log(arr.__proto__);[]
console.log(Array.prototype === arr.__proto__);//true
2、Object.getPrototypeof()方法
除了上面的两个方法来找到原型对象,也可以通过Object.getPrototypeof()方法来查找对象的原型对象
let arr = [1,2,3,4,5];
console.log(Object.getPrototypeof(arr)); //[]
console.log(arr.__proto__);//[]
console.log(Object.getPrototypeof(arr)===arr.__proto__);//true
3、constructor 属性
通过这个属性可以获取这个对象是怎么得到的
let arr = [1,2,3,4,5];
console.log(arr.constructor);//[function:Array];
4、 instanceof操作符
这个操作符的用处是来判断这个对象是不是一个构造函数;是的话返回true,不是的话就返回false
let arr = [1,2,3,4,5];
console.log(arr instanceof Array);//true
console.log(arr instanceof Number);//false
5、isPrototypeOf()方法
这个方法会返回一个布尔值,用于检测对象是否是实例对象的原型对象
let arr = [1,2,3,4,5];
console.log(Array.prototype.isPrototypeOf(arr));//true
console.log(arr.__proto__.isPrototypeOf(arr));//true
6、hasOwnProperty()方法
判断一个属性是定义再哪一个身上的,如果是对象本身的,则返回true,如果是从原型对象继承来的,则返回false
let person = {
arms:2,
legs:2,
}
let pizza = Object.create(person,{
name:{
value:"pizza",
writable:false,
enumerable:true
},
age:{
value:18,
enumerable:false
}
})
console.log(pizza.hasOwnProperty("name")); // true
console.log(pizza.hasOwnProperty("age")); // true
console.log(pizza.hasOwnProperty("arms")); // false
console.log(pizza.hasOwnProperty("legs")); // false
描述对象
在日常生活中,我们向别人安利或者介绍一样东西的时候,往往会从两方面出发,他的外观和功能。程序里,也是通过这两个来描述的
对象特征:又被称为成员属性,一般通过变量来存储。例如一个手机,描述这个手机的颜色,可以用color来存储,这个变量可以称为手机的一个属性。
对象功能:除了描述一个对象的特征以外,我们往往还需要他有什么作用
构造函数创建对象
用于实例化对象的函数,我们将其称为构造函数。但是有一个规矩,就是构造函数的函数名首字母必须得是大写
let Computer = function(name,price){
this.name = name;
this.price = price;
}
Computer.prototype.showSth = function(){
console.log(`这是一部${this.name}手机,价值${this.price}元`);
}
let apple = new Computer("苹果",12000);
console.log(apple.name);//苹果
console.log(apple.price);//12000
apple.showSth();这是一部苹果手机,价值12000元
let asus = new Computer("华为,"10000");
console.log(asus.name);//华为
console.log(asus.price);//10000
asus.showSth();//这是一部华为手机,价值10000元
构造函数显式返回内容
函数中可以通过return返回数据,构造函数里也一样。如果返回的是object对象,那么这次运算的结果就是这个对象。反之则不是
没有返回object对象:
let Computer = function (name, price) {
this.name = name;
this.price = price;
}
Computer.prototype.showSth = function () {
console.log(this);//这个是打印出this值
}
const apple = new Computer("苹果", 12000);
console.log(apple.name); //苹果
apple.showSth(); // Computer { name: '苹果', price: 12000 }
这是个返回objec对象:
let Computer = function (name, price) {
this.name = name;
this.price = price;
//这个是返回一个object的对象
return {
name: "pizza",
showSth: function () {
console.log(this); //打印出这个this值的对象
}
}
}
Computer.prototype.showSth = function () {
console.log(this); //打印出这个this值的对象
}
const apple = new Computer("苹果", 12000);
console.log(apple.name); // pizza
apple.showSth(); // { name: 'pizza', showSth: [Function: showSth] }
ECMAScript 6中类的声明
从ECMAScript 6开始,javaScript已经开始越来越贴近其他的高级语言,在ECMAScript 6中有了类这个概念,使用class关键字来声明一个类来,然后从类里面实例化对象
class Computer {
//构造器
constructor(name, price) {
this.name = name;
this.price = price;
}
//原型方法
showSth() {
console.log(`这是一台${this.name}电脑`);
}
}
const apple = new Computer("苹果", 12000);
console.log(apple.name); // 苹果
console.log(apple.price); // 12000
apple.showSth(); // 这是一台苹果电脑
静态方法
静态方法的好处在于不需要实例化对象,直接通过类就能够进行方法的调用。
在ECMAScript 6 中要创建静态方法,可以在方法前面添加关键字static:
class Computer {
//构造器
constructor(name, price) {
this.name = name;
this.price = price;
}
//原型方法
showSth() {
console.log(`这是一台${this.name}电脑`);
}
//静态方法
static comStruct() {
console.log("电脑是由显示器、主机、键盘和鼠标组成");
}
}
Computer.comStruct();//电脑是由显示器、主机、键盘和鼠标组成
如果是构造函数,也可以模拟静态方法,直接将方法挂在构造函数上:
const Computer = function (name, price) {
this.name = name;
this.price = price;
}
Computer.prototype.showSth = function () {
console.log(`这是一台${$this.name}电脑`);
}
//静态方法,直接通过Computer这个构造函数来调用
Computer.comStruct = function () {
console.log("电脑是由显示器、主机、键盘和鼠标组成");
}
Computer.comStruct(); //电脑是由显示器、主机、键盘和鼠标组成
基于对象创建新对象
1、Object.create() 方法,用于克隆对象来使用;
const person = {
arms :2,
legs:2,
walk(){
console.log("walking");
}
}
let pizza = Object.create(person);
console.log(pizza.arms);//2
console.log(pizza.legs);//2
console.log(pizza__proto__===person);//true;
pizza.walk();//walking
封装就是隐藏细节,不被外界所看到
const Computer = function (name, price) {
this.name = name;
const _price = price;
}
Computer.prototype.showSth = function () {
console.log(`这是一台${this.name}电脑`);
}
const apple = new Computer("苹果", 12000);
console.log(apple.name); // 苹果
console.log(apple.price); // undefined
console.log(apple._price); // undefined
在属性前面加上进行封装,这时候就变成了私有属性,外部不能访问,也就达到了封装的目的。 如果我们自己想要访问的话,加上就行
const Computer = function (name, price) {
this.name = name;
const _price = price;
this.sayPrice = function () {
console.log(`价格为{_price}`);
}
}
Computer.prototype.showSth = function () {
console.log(`这是一台${this.name}电脑`);
}
const apple = new Computer("ຎ", 12000);
apple.sayPrice(); //价格为12000
方法借用:
Function.apply(obj҅args)方法能接收两个参数//数组的形式
Function.call(obj҅[param1[҅param2[҅...[҅paramN]]]])//接收的是参数列表