JavaScript面向对象

JavaScript面向对象

对象类型的使用

在数据类型中我们提到还有一种特别的类型:对象类型。
  对象类型涉及到JavaScript的各个方面,所以掌握对象类型非常重要;
  对象类型是一种存储键值对(key-value)的更复杂的数据类型;
为什么需要对象类型呢?
  基本数据类型可以存储一些简单的值,但是现实世界的事物抽象成程序时,往往比较复杂;
  比如一个人,有自己的特性(比如姓名、年龄、身高),有一些行为(比如跑步、学习、工作);
  比如一辆车,有自己的特性(比如颜色、重量、速度),有一些行为(比如行驶);
这个时候,我们需要一种新的类型将这些特性和行为组织在一起,这种类型就是对象类型。
  对象类型可以使用{…}来创建的复杂类型,里面包含的是键值对(“key: value”);
  键值对可以是属性和方法(在对象中的函数称之为方法);
  其中key是字符串(也叫做属性名property name ,ES6之后也可以是Symbol类型,后续学习);
  其中value可以是任意类型,包括基本数据类型、函数类型、对象类型等;

对象的创建方法

  对象的创建方法有很多,包括三种:
  对象字面量(Object Literal):通过{}
  new Object+动态添加属性;
  new 其他类
  例如:
    // 1.对象的自变量
    var obj={
      name:"hdc"
    }
    // 2.new Object()
    var boj2 = new Object()
    obj2.name = "kebo"
    // 3.new 其他类()
    function person(){}
    var obj3 =  new person()

对象的常见操作

    访问对象的属性;
    修改对象的属性;
    添加对象的属性;
    删除对象的属性;
  案例:
       // 访问对象中的属性
        console.log(info.name)
        console.log(info.friend.name)
        info.running()
      // 3.修改对象属性
        info.age = 25;
        console.log(info.age)
        info.running = function(){
          alert("I am running!")
        }
        info.running()
      // 4.添加对象的属性
      info.height = 1.88
      info.studying = function(){
        console.log("I am studying!")
      }
      console.log(info)
      // 5.删除属性
      // delete关键字
        delete info.age
        delete info.height
        console.log(info)

[]和""的使用

这是因为点符号要求 key 是有效的变量标识符
不包含空格,不以数字开头,也不包含特殊字符(允许使用 $ 和 _);
这个时候我们可以使用方括号:
方括号运行我们在定义或者操作属性时更加的灵活;
      // 方括号使用
        var obj = {
        name:"hdc",
        "my friend":"kebo",
        "eating something":function(){
          console.log("eating something")
        }
      }
      console.log(obj["my friend"])
      // 调用函数
      obj["eating something"]()
      var eatKey = "eating something";
      obj[eatKey]()

对象的遍历方式

对象的遍历(迭代):表示获取对象中所有的属性和方法。
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组;

// 遍历方式一:普通for循环
var infoKeys = Object.keys(info);
for(var i = 0 ;i<infoKeys.length; i++){
  var key = infoKeys[i]
  var value = info[key]
  console.log(`key:${key},value:${value}`) 
}

// 遍历方式二:for in 遍历方法
for (var key in info){
  var value = info[key]
  console.log(`key:${key},valuep:${value}`)
}

值类型和引用类型

栈内存和堆内存

  我们知道程序是需要加载到内存中来执行的,我们可以将内存划分为两个区域:栈内存和堆内存。
  !原始类型占据的空间是在栈内存中分配的;
  !对象类型占据的空间是在堆内存中分配的;

值类型和引用类型

  !原始类型的保存方式:在变量中保存的是值本身所以原始类型也被称之为值类型;
  !对象类型的保存方式:在变量中保存的是对象的“引用”所以对象类型也被称之为引用类型;

函数的this指向

  为什么需要this?
    在常见的编程语言中,几乎都有this这个关键字(Objective-C中使用的是self),但是JavaScript中的this和常见的面向对象语言中的this不太一样:
    常见面向对象的编程语言中,比如Java、C++、Swift、Dart等等一系列语言中,this通常只会出现在类的方法中。
    也就是你需要有一个类,类中的方法(特别是实例方法)中,this代表的是当前调用对象;
  但是JavaScript中的this更加灵活,无论是它出现的位置还是它代表的含义;
  我们来看一下编写一个obj的对象,有this和没有this的区别:
  案例:
    // 第二种方法
      var info = {
        name: "hdc",
        running:function(){
          console.log("running",info.name)
        },
        eatting:function(){
          console.log("eatting",info.name)
        },
        studying:function(){
          console.log("studying",info.name)
        },
      }
      info.running()
      info.eatting()
      info.studying()
      // 第三种方法
      var info = {
        name: "hdc",
        running:function(){
          console.log("running",this.name)
        },
        eatting:function(){
          console.log("eatting",this.name)
        },
        studying:function(){
          console.log("studying",this.name)
        },
      }
      info.running()
      info.eatting()
      info.studying()

this指向什么?

  目前掌握两个this的判断方法:
  以默认的方式调用一个函数,this指向window;
  通过对象调用,this指向调用的对象;

工厂方法创建对象

  我们可以想到的一种创建对象的方式:工厂函数
  我们可以封装一个函数,这个函数用于帮助我们创建一个对象,我们只需要重复调用这个函数即可;
  工厂模式其实是一种常见的设计模式;
  
  <!-- 工厂函数--->是一种设计模式 -->
  <script>
  function createPerson(name,age,height,address){
    var p = new Object();
    p.name = name;
    p.age = age;
    p.height = height;
    p.address = address
    p.running = function(){
      console.log(`${this.name}在跑步`)
    }
    p.eatting = function(){
      console.log(`${this.name}在吃东西`)
    }
    return p 
  }
  var p1 = createPerson("hdc",18,1.88)
  var p2 = createPerson("hdc1",19,1.88)
  var p3 = createPerson("hdc2",20,1.88)
  console.log(p1,p2,p3)
  console.log(p1.running(),p2.running(),p3.running(),)
</script>

构造函数和类

  工厂方法创建对象有一个比较大的问题:我们在打印对象时,对象的类型都是Object类型
      但是从某些角度来说,这些对象应该有一个他们共同的类型;
      下面我们来看一下另外一种模式:构造函数的方式;
  我们先理解什么是构造函数?
      构造函数也称之为构造器(constructor),通常是我们在创建对象时会调用的函数;
      在其他面向的编程语言里面,构造函数是存在于类中的一个方法,称之为构造方法;
      但是JavaScript中的构造函数有点不太一样,构造函数扮演了其他语言中类的角色;
  也就是在JavaScript中,构造函数其实就是类的扮演者:
      比如系统默认给我们提供的Date就是一个构造函数,也可以看成是一个类;
      在ES5之前,我们都是通过function来声明一个构造函数(类)的,之后通过new关键字来对其进行调用;
      在ES6之后,JavaScript可以像别的语言一样,通过class来声明一个类;
  那么类和对象到底是什么关系呢?
      对象是由类创建出来的

JavaScript中的类(ES5)

我们前面说过,在JavaScript中类的表示形式就是构造函数。
JavaScript中的构造函数是怎么样的?
    构造函数也是一个普通的函数,从表现形式来说,和千千万万个普通的函数没有任何区别;
    那么如果这么一个普通的函数被使用new操作符来调用了,那么这个函数就称之为是一个构造函数;
如果一个函数被使用new操作符调用了,那么它会执行如下操作:
    1. 在内存中创建一个新的对象(空对象);
    2. 这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性;(后面详细讲);
    3. 构造函数内部的this,会指向创建出来的新对象;
    4. 执行函数的内部代码(函数体代码);
    5. 如果构造函数没有返回非空对象,则返回创建出来的新对象;
案例:
     // JavaScript已经默认提供了给我们可以更加符合JavaScript思维方式(面向对象)的一种创建对象规则
        function Person(name,age,height,address){
          this.name = name;
          this.age = age;
          this.height = height;
          this.address = address
          this.running = function(){
            console.log(`${this.name}在跑步`)
          }
        }
        var stu1 = new Person("hdc",18,1.88)
        console.log(stu1)

全局对象window

   // 浏览器中存在一个全局对象Object -->window
        console.log(window)
   // window对象的作用
  // 作用一:查找变量,最终会找
  到window头上
  
  // 作用二:将一些浏览器全局提供给我们的变量/函数/对象,放在window对象上面
  // 作用三:使用var定义的变量会被默认添加到window上面
  function foo(){
    // 自己的作用域
    // console.log(message)
    alert("Hello  World")
    
    // 创建一个对象
    var obj = new Object()

    // DOM
    console.log(document)
  }

new创建对象

posted @ 2024-10-20 02:01  韩德才  阅读(10)  评论(0编辑  收藏  举报