js面向对象

86 阅读5分钟

面向对象(Object-oriented programming)的思想

  1. 面向过程,就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步步实现,使用时在一个个调用函数就行了
  2. 面向对象,就是把事务分解成一个个对象,然后由对象之间分工合作完成。面向对象是以对象功能来划分问题

举个最简单点的例子,就是把大象放进冰箱。

面向过程的思路

打开冰箱门
把大象塞进冰箱
关冰箱门

面向对象的思路,是赋予冰箱开门关门的操作,给大象进门的操作,然后冰箱和大象两个对象合作完成任务;

面向过程的优点:性能比面向对象高,比较适合和硬件联系紧密的东西

面向对象的优点:易维护、易复用、易扩展、更适合多人合作的大项目。

对象:

对象(object)是大括号定义的无序的数据集合,由键值对构成

对象也是变量。但是对象包含很多值。

这段代码把多个值(20230001, 21, 张三)赋给名为 student的变量

var student= {id:"20230001", age:21, name:"张三"};

值以名称:值对(即键值对)的方式来书写(名称和值由冒号分隔)。

JavaScript 对象是被命名值的容器。

对象属性

(JavaScript 对象中的)名称:值对被称为属性

我们也可以理解为对象的状态或对象的数据

var student ={
    status:true
}

对象方法

对象也可以有方法

方法是在对象上执行的动作

方法以函数定义被存储在属性中。

var student ={
    sayhello:function(){
        console.log("hello")
    },
    // 简写
    sayhi(){
        console.log("hi")
    }
}

实例

var person = {
  firstName: "Bill",
  lastName : "Gates",
  id       : 678,
  fullName : function() {
    return this.firstName + " " + this.lastName;
  }
};

访问对象属性

objectName.propertyName

或者

objectName["propertyName"]

访问对象方法

objectName.methodName()

对象的声明方式

  1. 声明字面式对象

  2. 通过Object类创建对象

    1. // 创建空对象
      let obj1 = {}
      let obj2 = new Object();
      // 添加属性
      obj1.key1 = "value1"
      obj2.key2 = 12
      obj1["key"] = false
      // 添加方法
      obj2.hi=function(){
          console.log("hi")
      }
      

变量提升

从概念的字面意义上说,“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。

var

在 ES6 之前,作用域分为两种:

  • 全局作用域中的对象在代码中的任何地方都可以访问,其生命周期伴随着页面的生命周期。
  • 函数作用域是在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。函数执行结束之后,函数内部定义的变量会被销毁。
  1. 使用 var 声明的变量是全局作用域或者函数作用域
function example() {
    var age=10;    
}
console.log(age);//ReferenceError
  1. 使用 var 声明的变量可以被重新声明以及更新。
var hello =1;
var hello =false;
console.log(hello); //false
  1. 使用 var 声明的变量存在变量提升。
console.log(abc) // undefined
var abc = "hi"
console.log(abc) // hi

let,const

let 区别于var,是有块级作用域的,即在带有 let 的块中声明的变量只能在该块中使用。

块级作用域,就是使用一对大括号包裹的一段代码,比如函数、判断语句、循环语句,甚至一个单独的{}都可以被看作是一个块级作用域(注意,对象声明中的{}不是块级作用域)。

  1. 不能在其作用域内被重复声明
let a=10;
let a; // 语法错误
  1. 由于暂时性死区,不能在声明前使用
 console.log(b) //error
 let b=10;
 console.log(b) //10
  1. let 声明的变量也会被提升,但不会被初始化为undefined。

ES6 规定:如果区块中存在 let 和 const,这个区块对这两个关键字声明的变量,从一开始就形成了封闭作用域。假如尝试在声明前去使用这类变量,就会报错。这一段会报错的区域就是暂时性死区。

一般定义变量分为创建、初始化、赋值三阶段,未初始化的变量无法使用,这个就是暂时性死区的由来。

let在JavaScript运行中实际上会被提升,但由于“暂时性死区”的存在,不能在声明中使用let变量。 let / const 不存在变量提升是不完全正确的,只能说由于暂时性死区的存在使得我们无法直观感受到变量提升的效果。

const,与let的机制类似,区别是:

  1. const声明时必须进行初始化,且初始化后值不可再修改(即不存在赋值过程)。
const a=10;
a=20 // error
  1. 当然const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。使用 const 定义的对象或者数组,其实是可变的
const c=[1,2,3]
c[2]=10;
console.log(c); // [ 1, 2, 10 ]
  1. 但是我们不能对常量对象重新赋值
const b={a:10}
b={} //error

函数是一等公民

  • 预处理时,函数提升优先级高于变量,且函数声明不会被变量声明覆盖
var sayhi;
console.log(sayhi)
sayhi();
function sayhi() {
    console.log("hi")
}
  • 但是会被变量赋值覆盖
var sayhi=10;
console.log(sayhi)//10
sayhi();//error
function sayhi() {
    console.log("hi")
}
  • 通过函数表达式定义函数,只提升了声明,没有提升赋值
fn();// error
console.log(fn) //undefined
var fn = function () {
    console.log(1)  
}

小练习:

console.log(a);//
a();//
var a;
a=function(){console.log(1);}
a();//
function a(){console.log(2);}
a=3;
console.log(a);//