js 面向对象总结

编程范式

1:命令式编程

命令机器去做事情,这样不管你想要的是什么,他都会按照你的命令实现。

1:面向过程

分析解决问题所需要的步骤,然后一步步实现。

2:面向对象

面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述解决问题中华步骤的行为。
**注:**面向对象并不是完全脱离面向过程的,也就是说,就算好似采用面向对象的思想,里面也会有面向过程的步骤,只不过通过面向对象可以给我们节省了很多步骤,因为这些步骤通过对象本身实现了。

特征

#####1:封装
内部运作隐藏在对象里,只有基本功能暴露给最终用户。
#####2:继承
新对象继承一个现有对象的特性,然会添加一些新的特效。
#####2:多态
不同的对象可以共享相同的方法。还能够用一些特定的方法覆盖原有的方法。

类是对象的一种概括,而对象是类的一种具体实现。

例:
class Person{ 
 public $name; 
 public $gender;
 public $age; 
  function __construct($name, $gender, $age){
          $this->name = $name;         
          $this->gender = $gender;        
          $this->age = $age; 
  } 
2:声明式编程

告诉机器你想要的是什么,让机器想出如何去做。

1:领域专用语言

DSL:主要指一些对应专门领域的高层编程语言,和通用编程语言的概念相对。

2:函数编程

是一种编程模型,将计算机运算看作是数学中函数的计算。在函数式编程中,变量只是一个名称,而不是存储单元。

####原型对象
在js中,每一个对象,都有一个原型对象。而原型对象上面也有一个自己的原型对象,一层一层向上找,最终会到达null。
####对象分类

1:原生对象

内置对象
js中本身所内置的。
自定义对象
开发人员自定义的对象

2:宿主对象

基于对象创建新对象

    const person = {    
    arms: 2,    
    legs: 2,    
    walk() {        console.log('walking');    } 
    } 
    const xiejie = Object.create(person); console.log(xiejie.arms); // 2 
    console.log(xiejie.legs); // 2 xiejie.walk(); // walking 
    console.log(xiejie.__proto__ === person); // true
原型相关方法
1: prototype 和_proto_ c

prototype是构造函数上面的一个属性,指向一个对象,这个对象是该构造函数实例化出来的对象的原型对象。实例化出来的对象可以通过_proto_来找到自己的原想对象。

const arr = [1,2,3,4,5]; console.log(Array.prototype);  console.log(arr.__proto__);
console.log(Array.prototype === arr.__proto__); 
2: 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属性
查对象构造函数

const arr = [1,2,3,4,5]; console.log(arr.constructor); // [Function: Array]

4.instanceof操作符
判断一个对象是否是一个构造函数的实例。返回true或false。

const arr = [1,2,3,4,5]; console.log(arr instanceof Array); // true 
console.log(arr instanceof Number); // false
  1. isPrototypeOf() 方法
    返回一个布尔值,检测一个对象是否是一个实例对象的原型对象。

  2. hasOwnProperty()
    判断一个属性是定义在对想本身上面还是从原型对象上面继承而来。返回布尔值。

构造函数

1.构造函数创建对象

使用函数来模拟其他面向对象语言中的类。
用于实列化对象的函数,我们将其称之为构造函数。
咧:

const Computer = function(name,price){
    this.name = name;
    this.price = price; 
    } 
    Computer.prototype.showSth = function(){ 
       console.log(`这是一台{this.name}电脑`); 
       }

当使用new运算符调用函数时,该函数总会返回一个对象,通常情况下,构造函数里面的this就指向返回这个对象。
咧:

const Computer = function(name,price){
    this.name = name;    this.price = price; 
    } 
    Computer.prototype.showSth = function(){
     console.log(this); // 打印出this所指向的对象
  console.log(`这是一台{this.name}电脑`); 
  } 
  const apple = new Computer("苹果",12000);
   console.log(apple.name);// 苹果
   console.log(apple.price);// 12000 
   apple.showSth();// Computer { name: '苹果 ', price: 12000 } 这是一台苹果电脑
   const asus = new Computer("华硕",5000); 
   console.log(asus.name);// 华硕
   console.log(asus.price);// 5000 
   asus.showSth();// Computer { name: ' 华硕', price: 5000 } 这是一台华硕电脑
2.构造函数显式返回内容

构造函数显式返回object类型对象的区别
咧:

const 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 }
3.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(); // 这是一台苹果电脑
4.静态方法

又被称为类方法,就是通过类来调用的方法。静态方法的好处在于不需要实例化对象,直接通过类就能够进行方法的调用。
咧:

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(); // ??????????????

面对对象3大特征

1.封装

指隐藏内部的细节,不暴露在外面。目的就是将信息隐藏。

const Computer = function(name,price){    
this.name = name;    
this.price = price; 
this.sayPrice = function () {        
console.log(`价格${_price}`);    
 }
} 
Computer.prototype.showSth = function () {    
console.log(`这是一台${this.name}电脑`); 
} 
const apple = new Computer("苹果", 12000); 
apple.sayPrice(); // 价格12000
2.继承
1.继承基本介绍

面向对象里面的继承是指一个子类去继承一个父类。子类继承父类之后,父类所有的属性和方法都自动拥有了
好处:代码复用。
缺点:1)会出现“大猩猩与香蕉”问题
2)也会遇到“菱形继承”(只会在多继承里面才会出现)

2.对象冒充

对象冒充,就是用父类(构造函数)去充当子类的属性
咧:

const Person = function (name, age) {    
this.name = name;    
this.age = age; 
} 
const Student = function (name, age, gender, score) {    
this.temp = Person; // 将Person构造函数Student的一个属性   
this.temp(name, age); // 给Person构造函数里面的this.name以及this.age赋值   
delete this.temp; // this.temp 已经无用,将其删除  
this.gender = gender;    
this.score = score; 
} 
const xiejie = new Student("哈哈", 18, "男", 100); console.log(xiejie.name); // 哈哈
console.log(xiejie.age); // 18 
console.log(xiejie.gender); //男
console.log(xiejie.score); // 100

使用对象冒充来实现继承也有一个缺陷,那就是无法继承到原型对象上面的属性。
咧:

const Person = function (name, age) {    
this.name = name;    
this.age = age; 
}
Person.prototype.test = "this is a test";
const Student = function (name, age, gender, score) {    
this.temp = Person; // 将Person构造函数Student的一个属性   
this.temp(name, age); // 给Person构造函数里面的this.name以及this.age赋值   
delete this.temp; // this.temp 已经无用,将其删除  
this.gender = gender;    
this.score = score; 
} 
const xiejie = new Student("哈哈", 18, "男", 100); console.log(xiejie.name); // 哈哈
console.log(xiejie.age); // 18 
console.log(xiejie.gender); //男
console.log(xiejie.score); // 100
console.log(xiejie.test); // undefined

3.方法借用模式

call()和apply()方法
Function.apply(obj?args)方法能接收两个函数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args->arguments)
Function.call(obj?[param1[?param2[?..[?paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表

call()实现继承示列:

const Person = function (name, age) {    
this.name = name;    
this.age = age; 
} 
Person.prototype.test = "this is a test"; 
const Student = function (name, age, gender, score) {    
// 将Person构造函数应用到this 里面   
// this 后面是参数 
Person.call(this, name, age);    
this.gender = gender;    
this.score = score; 
} 
const xiejie = new Student("哈哈", 18, "男", 100); console.log(xiejie.name); // 哈哈
console.log(xiejie.age); // 18 
console.log(xiejie.gender); // 男
console.log(xiejie.score); // 100 
console.log(xiejie.test); // undefined

apply()实现继承示列:

const Person = function (name, age) {    
this.name = name;    
this.age = age; 
} 
Person.prototype.test = "this is a test"; 
const Student = function (name, age, gender, score) {    
// 将Person构造函数应用到this 里面   
// this 后面是参数 
## Person.apply(this,[name,age]);  
this.gender = gender;    
this.score = score; 
} 
const xiejie = new Student("哈哈", 18, "男", 100); console.log(xiejie.name); // 哈哈
console.log(xiejie.age); // 18 
console.log(xiejie.gender); // 男
console.log(xiejie.score); // 100 
console.log(xiejie.test); // undefined
4.原型继承

这种方式的核心思路就是改变构造函数的prototype的指向,使其指定到我们想要继承的类的实列对象上面
咧:

const Person = function (name, age) {    
this.name = name;    
this.age = age; 
} 
Person.prototype.test = "this is a test"; 
const Student = function (name, age, gender, score) {    
// 将Person构造函数应用到this里面 
// this后面是参数  
Person.apply(this, [name, age]);    
this.gender = gender;    
this.score = score; 
} 
Student.prototype = new Person(); // 改变Student构造函数的原型对象
const xiejie = new Student("哈哈", 18, "男", 100); console.log(xiejie.name); //哈哈
console.log(xiejie.age); // 18
console.log(xiejie.gender); // 男
console.log(xiejie.score); // 100 
console.log(xiejie.test); // this is a test
5.ECMAScript 6 继承方式

可以使用extends关键字来实现继承
咧:

class Person {    
constructor(name, age) {        
this.name = name;        
this.age = age;    
}    
sayName() {        
console.log(`my name is ${this.name}`);    
} 
} 
class Student extends Person {    
constructor(name, age, gender, score) {        
super(name, age); // super代表访问父类的构造函数    
this.gender = gender;        
this.score = score;    
}    
learn() {        
console.log("I\'m learning");    
} 
} 
const xiejie = new Student("xiejie", 18, "male", 100); console.log(xiejie.name); // xiejie 
console.log(xiejie.age); // 18 
console.log(xiejie.gender); // male 
console.log(xiejie.score); // 100 
xiejie.sayName(); // my name is xiejie 
xiejie.learn(); // I'm learning

3多态

1.多态简介

含义:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。
换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。

2.实现多态
const duck = {    
name: "鸭子",    
makeSound: function () {        
console.log("嘎嘎嘎");    
} 
}; 
const chicken = {    
name: "鸡",    
makeSound: function () {        
console.log("咯咯咯");  
}
}; 
const animalSound = function (obj) {    
obj.makeSound(); 
} 
animalSound(duck); // 嘎嘎嘎
animalSound(chicken); // 咯咯咯

在 ECMAScript 6 中我们也可以在子类里面书写和父类相同的方法名来进行覆盖
咧:

class Person {    
constructor(name, age) {        
this.name = name;        
this.age = age;    
}    
sayName() {        
console.log(`my name is ${this.name}`);    
} 
}
class Student extends Person {    
constructor(name, age, gender, score) {        
super(name, age); // super代表访问父类的构造函数     
this.gender = gender;        
this.score = score;    
}    
sayName() {        
console.log(`haha,I'm ${this.name}`);    
}    
learn() {        
console.log("I\'m learning");    
} 
} 
const xiejie = new Student("哈哈", 18, "男", 100); 
xiejie.sayName(); // haha,I'm 哈哈
const song = new Person("宋", 20); 
song.sayName(); // my name is 宋
3.多态的意义

多态的最根本的好处在于,你不必再向对象询问”你是什么类型“后根据得到的答案调用对象的某个行为,你只需要调用该行为就是了,其他的一切多态机制会为你安排妥当。

this的指向

1.this指向的默认情况
1.this指向当前对象

如果是在对象里面使用this,则指向当前对象。this可以用在方法内,获取对对象属性的访问。。
咧:

const person = {    
name: 'xiejie',    
age: 18,    
intro: function () {        
console.log(this); // { name: 'xiejie', age: 18, intro: [Function: i ntro] }        
console.log(`My name is ${this.name},I'm ${this.age} years old`); // My name is xiejie,I'm 18 years old    
} 
} 
person.intro();
2.普通函数中的this指向

如果是普通调用函数,this则指向全局对象
咧:

const test = function () {    
console.log(this); // global 对象   
// 在 node里面 , 全局对象就是global 对象  
// 如果是在浏览器里面,那么全局对象代表window对象
} 
test();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值