2.7 JS对象的使用

1.对象类型的使用

1.1认识对象类型

对象类型是一种存储键值对(key-value)的更复杂的数据类型

为什么需要对象类型呢?

基本数据类型可以存储一些简单的值,但是现实世界的事物抽象成程序的时候,往往比较复杂;

比如一个人,有自己的特性(比如姓名、年龄、身高),有一些行为(比如跑步、学习、工作);

比如一辆车,有自己的特性(比如颜色、重量、速度),有一些行为(比如驾驶);

这个时候,我们需要一种新的类型将这些特性和行为组织在一起,这种类型就是对象类型。

1.对象类型可以使用(…)来创建的复杂类型,里面包含的是键值对(“key:value”);

2.键值对可以是属性和方法(在对象中的函数称之为方法);

<body>
  <script>
    /*
      两个术语:函数/方法
        函数(function):如果在JavaScript代码中通过function默认定义一个结构,称之为函数;
        方法(method):如果将一个函数放到对象中,作为对象的一个属性,那么将这个函数称之为方法
    */

    //函数
    function foo(){

    }
    
    var person={
      //key:value
      //这里加双引号和不加双引号是一样的 但是有时候不能省略比如 "my frient":"kobe"
      "name":"Joby",
      age:18,
      //值的类型可以是对象等多种类型
      "my frient":{
        name:"kobe",
        age:21
      },
      height:190,
      run: function(){
        console.log("running")
      },
      //方法
      study:function(){
        console.log("studying")
      }
    }
  </script>
</body>

3.其中key是字符串(也叫做属性名property name ,Es6之后也可以是Symbol类型,后续学习);

key是字符串类型,但是在定义对象的时候,大部分情况下引号都是可以省略的

4.其中value可以是任意类型,包括基本数据类型、函数类型、对象类型等;

1.2创建对象和使用对象

对象的创建方法有很难多,包括三种:

对象字面量(Object Literal):通过{}

new Object+动态添加属性;

new 其他类;

<body>
  <script>

    //1.对象字面量
    var obj1={
      name:"Jobe"
    }

    //2.new Object()
    //Object构造函数
    var obj2 = new Object()
    obj2.name ="Jony"
    
    //3.new 其他类()
    function Person() {}
    var obj3 = new Person()
    
    //这里需要了解new是什么 以及构造函数是什么 为什么要怎么写 后续。。
  </script>
</body>

注意:属性之间是要用逗号隔开的

1.3对象的常见操作

对象的使用过程包括如下操作:

访问对象的属性;

修改对象的属性;

添加对象的属性;

删除对象的属性;

<body>
    <script>
      
      //1.定义了一个对象
      var info={
        name:"Joby",
        age:18,
        friend:{
          name:"Bogo",
          age:19
        },
        running:function(){
          console.log("running")
        }
      }

      //2.访问对象中的属性
      console.log(info.name)
      console.log(info.friend.name)
      info.running

      //3.修改对象中的属性
      info.age=25
      info.running=function(){
        alert("I am running~")
      }
      console.log(info.age)
      info.running

      //4.添加对象中的属性
      //如果对象原来中没有这个属性或者方法,就会动态添加到原来的对象中,这就是JavaScript不同与其他语言的一大特性
      info.height=1.99
      info.studying=function(){
        console.log("I am studying")
      }
      console.log(info)

      //5.删除属性
      //delete关键字(操作符)
      delete info.age
      delete info.height
      console.log(info)
    </script>
</body>

1.4对象的方括号和练习

为什么需要使用方括号呢?

对于多次属性来说,JavaScript是无法理解的。

这是因为点符号要求key是有效的变量标识符

不包括空格,不能以数字开头,也不包含特殊字符(允许使用$和_);

这个时候我们可以使用方括号;

方括号运行我们在定义或者操作属性的时候更加灵活;

<body>
    <script>
      var obj={
        name: "Jobe",
        "my friend":"kobe",
        "eating something":function(){
          console.log("eating~")
        }
      }

      console.log(obj["my friend"])
      console.log(obj.name)
      console.log(obj["name"])
      //访问方法的方法:使用方括号访问方法的时候后面必须加上()
      //方法一:
      console.log(obj["eating something"]())
      //方法二:
      var eatKey="eating something"
      obj[eatKey]()
    </script>
</body>

1.5对象的遍历

对象的遍历(迭代):表四获取对象中所有的属性和方法。

Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组;

遍历方式一:普通for循环

遍历方式二:for in 遍历方法

遍历方式三:for of 遍历方法

<body>
    <script>

      var info = {
        name: "Jobe",
        age: 18,
        height: 1.99
      }

      //对对象进行遍历
      //方式一:普遍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},value:${value}`)
      }

      //方式三:for...of:默认是不支持这种方式 数组支持,对象不支持
      // for (var foo of info){

      // }
    </script>
</body>

2.值类型和引用类型

2.1栈内存和堆内存概念 (补充)

 

我们知道程序是需要加载到内存中来执行的,我们可以将内存划分为两个区域:

栈内存和堆内存。

原始类型占据的空间是在栈内存中分配的

对象类型占据的空间是在堆内存中分配的

2.2值类型和引用类型

原始类型的保存方式:在变量中保存的是值本身

所以原始类型也被称之为值类型;

对象类型的保存方式:在变量中保存的是对象的”引用“

所以对象类型也被称之为引用类型

2.3JavaScript中一些现象的内存表现

现象一:两个对象的比较

现象二: 引用的赋值

现象三:值传递

现象四:引用传递,但是在函数中创建了一个新对象,没有对传入的对象进行修改

现象五:引用传递,但是对传入的对象进行修改

3.函数的this指向

3.0this的使用

技巧:看是否有被其他的调用来调用,还是默认的

      //函数中是由一个this的变量,this变量在大多数情况下会指向一个对象
      //arguments保存的是传入的所有的参数

      //情况一:如果普通的函数被默认调用,那么this指向的是window
      function foo(name, age) {
        console.log(arguments)
        console.log(this)
      }
      foo("abc",123)

      function sayHello(name) {
        console.log(this)
      }
      sayHello()
      //情况二:如果函数它是被一个对象来引用并且调用它,那么this会指向这个对象(调用的那个调用)
      var obj = {
        name: "nebe",
        running: function() {
          console.log(this)
          // console.log(obj)
          // console.log(this ===  obj)
        }
      }
      obj.running()
      //情况二:如果函数它是被一个对象来引用并且调用它,那么this会指向这个对象(调用的那个调用)
      var obj = {
        name: "nebe",
        running: function() {
          console.log(this)
          // console.log(obj)
          // console.log(this ===  obj)
        }
      }
      // obj.running()

      //特殊情况
      //1.题目一
      var fn =obj.running
      fn()
          //2.题目二
  function bar(){
        console.log(this)
      }
      var obj = {
        name: "kk",
        bar: bar
      }
      obj.bar()

3.1this在开发中的作用

在常见的编程语言中,几乎都有this这个关键字(Objective-C中使用的是self),但是JavaScript中的this和常见的面向对象语言中的this不太一样

常见面向对象的编程中,比如Java、C++、Swift、Dart等等一系列语言中,this通常只会出现在类的方法中

也就是你需要有一个类,类中的方法(特别是实例方法中),this代表的是当前调用对象

(在其他的语言中this用在类中,但是在JavaScript中this可以用在对象中)

但是在JavaScript中this更加灵活,无论是它出现的位置还是它代表的含义;

我们来看一下编写一个obj的对象,有this和没有this的区别:

*********当我们把对象的名字改变的时候,那么里面的obj也要改成新的对象名字,this可以解决这个灵活性问题

this指向什么?

目前掌握两个this判断方法:

以默认的方式调用一个函数,this指向window;

通过对象调用,this指向调用的对象

(后续还会更新this的指向其他情况,但是这两个最常见)

      function foo() {
        console.log(this) //window
      }
      foo()

      var obj = {
        bar: function() {
          console.log(this) //obj
        }
      }
      obj.bar()

4.工厂方法创建对象(创建一系列对象的方式)

我们可以创建一种创建对象的方式:工厂函数

我们可以封装一个函数,这个函数用于帮助我们创建一个对象,我们只需要重复调用这个函数就可以;

工厂模式其实是一种常见的设计模式

通过工厂设计模式,自己定义了一个这样的函数

      //工厂函数(工厂生产student对象),只是一种设计模式
      function createStudent(name, age, height) {
        var stu = {}
        stu.name = name
        stu.age = age
        stu.height = height
        stu.running = function() {
          console.log("running~")
        }
        return stu
      }

      var sut1 = createStudent("a", 18, 1.88)
      var sut2 = createStudent("b", 18, 1.88)
      var sut3 = createStudent("c", 18, 1.88)

      console.log(sut1,sut2,sut3)

4.1创建一系列的对象的方式一(普通方式)

  <script>
    //创建一系列的学生对象
    var stu1 = {
      name: "a",
      age: 18,
      height: 1.88,
      running: function() {
        console.log("running~")
      }
    }
    var stu2 = {
      name: "b",
      age: 50,
      height: 1.88,
      running: function() {
        console.log("running~")
      }
    }
    var stu3 = {
      name: "c",
      age: 50,
      height: 1.88,
      running: function() {
        console.log("running~")
      }
    }
    </script>

4.2创建一系列的对象的方式二(工厂方式)

    <script>
      
      //for循环
      // for (var i = 0; i<3; i++) {
      //   var stu = {
      //     name: "a",
      //     age: 18,
      //     height: 1.88,
      //     running: function() {
      //       console.log("running~")
      //     }
      //   }
      // }
      // var obj1 = {}
      // var obj2 = {}
      //工厂函数(工厂生产student对象),只是一种设计模式
      function createStudent(name, age, height) {
        var stu = {}
        stu.name = name
        stu.age = age
        stu.height = height
        stu.running = function() {
          console.log("running~")
        }
        return stu
      }

      var sut1 = createStudent("a", 18, 1.88)
      var sut2 = createStudent("b", 18, 1.88)
      var sut3 = createStudent("c", 18, 1.88)

      console.log(sut1,sut2,sut3)
    </script>

5.构造函数和类

5.1创建一系列的对象的方式三(构造函数)常用

    <script>


      //JavaScript以及默认提供了我们可以更加符合JavaScript思维方式(面向对象的思维方式)的一种创建对象的规则
      //在函数中的this一般指向某一个对象

      /*
      如果一个函数被new操作符调用
      1.创建出来一个新的空对象
      2.让this指向这个空对象
      3.执行函数体的代码块
      4.如果没有明确的返回一个非空对象,那么this指向的对象会被自动返回
      */
      function coder(name, age, height) {
        this.name = name
        this.age = age
        this.height =  height
        this.running = function() {
          console.log("running~")
        }
      }

      //在函数调用的前面加上new 关键字(操作符)
      var stu1 = new coder("Jobe", 18, 1.88)
      var stu2 = new coder("Kobe", 30, 1.99)
      console.log(stu1, stu2)

      //总结:构造函数实际上就是帮助我们构造出来一个或者多个对象的
    </script>

5.2认识构造函数

工厂方法创建对象有一个比较大的问题:我们在打印对象时候,对象的类型都是Object类型

但是从某些角度说,这些对象应该有一个他们共同的类型;

下面我们来看一下另一种模式:构造函数的方式;

我们先理解什么是构造函数?

构造函数也称之为构造器(constructor),通常是我们在创建对象的时候会调用的函数;

在其他面向的编程语言里面,构造函数是存在于类中的一个方法,称之为构造方法;

但是JavaScript中的构造函数有一点不太一样,构造函数扮演了其他语言中类的角色;

也就是在JavaScript中,构造函数其实就是类的扮演者

比如系统默认给我们提供Date就是一个构造函数,也可以看成一个类

在ES5之前,我们都是通过function来声明一个构造函数(类)的,之后通过new关键字来对其进行调用;

在ES6之后,JavaScript可以像别的语言一样,通过class来声明一个类;

所以类和构造函数在JavaScript中非常相似

5.3JavaScript中的类和构造函数

在JavaScript中类的表示形式就是构造函数

JavaScript中的构造函数是怎么样的?

构造函数也是一个普通的函数,从表现形式来说,和千千万万个普通函数没有任何区别;

那么如果这么一个普通的函数被使用new操作符来调用了,那么这个函数就称之为一个构造函数

如果一个函数被使用new操作符调用了,那么它会执行如下操作:

1.在内存中创建一个新的对象(空对象);

2.这个对象内部的[prototype]属性会被赋值为该构造函数的prototype属性;(后面详细讲)

3.构造函数内部的this,会指向创建出来的新对象;

4.执行函数的内部代码(函数体代码)

5.如果构造函数没有返回非空对象,则返回创建出来的新对象;

5.4构造函数的补充

      //平时创建普通的对象
      //new Object()
      //相当于全局中有一个全局的构造函数,这个函数用于创建一个对象
      // function Object() {

      // }
      var obj1 = {}
      var obj2 = new Object()

      //创建一个自定义的类
      var obj3 = new Person()

事实上构造函数还有很多其他的特性:

比如原型、原型链、实现继承的方案

比如ES6中的类、继承的实现

6.new创建对象

      如果一个函数被new操作符调用

      1.创建出来一个新的空对象

      2.让this指向这个空对象

      3.执行函数体的代码块

      4.如果没有明确的返回一个非空对象,那么this指向的对象会被自动返回

      new这个关键字相当于替代了工厂方式创建对象中创建空对象和返回值两个操作。

7.面向对象编程和函数式编程

类:一系列的描述 

对象:类的具体的实例

 面向对象编程:将大量的重复操作看成是一个个类,在前端开发中用类用的很少,在java中 万物皆可对象

为什么在JavaScript用类用的少?

原因是JavaScript是支持多范式的编程语言:

意味着JavaScirpt这个语言支持函数式编程,支持面向对象编程,支持命令式编程,支持声明式编程。

为什么在前端中使用类很少,因为我们做的是前端页面,意味着我们使用的大部分对象,是从服务器(后端)给我们返回来的,我们前面直接可以使用就可以

 函数式编程:将大量的重复操作看成放到一个函数中

通过工厂方式创建对象会有一个弊端:就是类型是object类型

但是用构造函数创建对象,因为构造函数创建对象和类是一样的(在JS中),所以这里构造函数创建的对象的类型是构造函数声明的时候的类型

很多框架中使用类:

react组件化开发:使用类

class Axios:

8.对象的额外补充-全局对象window

      //浏览器中存在一个全局对象object->window

      console.log(window)

      //这个window有什么作用呢?

      //作用一:查找变量的时候,最终会找到window头上

      //作用二:将一些浏览器全局提供给我们的变量/函数/对象,放在window对象上面,比如  alert就是window提供的

      //作用三:使用var定义的变量会被默认添加到window上面(了解)

 

    <script>

      //浏览器中存在一个全局对象object->window
      console.log(window)

      //这个window有什么作用呢?
      //作用一:查找变量的时候,最终会找到window头上
      //作用二:将一些浏览器全局提供给我们的变量/函数/对象,放在window对象上面,比如alert就是window提供的
      //作用三:使用var定义的变量会被默认添加到window上面(了解)

      //使用var变量
      var message = "Hello World"

      //3.如果全局作用域也没有,会找到window
      //2.如果自己的作用域中没有这个变量,会去全局作用域查找
      function foo() {
      //1.message在查找这个变量的时候会先去 自己的的作用域
        // console.log(message)

        // alert("Hello World") //window提供的,会一层一层作用域去找到window console也是同理
        console.log(window.console === console)

        //创建一个对象
        // var obj =  new Object() //Object也是同理
        console.log(window.Object === Object)

        //DOM
        console.log(document) //这里也是同理,后续

        //window.message
        //注意这里的message执行的时候不是一层一层的从自己作用域开始查找,
        //而是直接查找到window这个作用域,在这个里面去找message,可见打印出来了
        console.log(window.message)
      }
      foo()
    </script>

9.对象的额外补充-函数也是一个对象 

既然函数也是一个对象,那么函数也具备对象操作的方法

      //引申一些别的知识
      //既然函数也是一个对象,那么函数也具备对象的操作方法
      var info = {}
      info.name = "abc"
      //同理
      function sayHello() {

      }
      sayHello.age = 18
      console.log(sayHello.age)

      //同理
      function Dog() {

      }
      //构造函数上(类上面)添加的函数,称之为类方法
      Dog.running = function(){}
      Dog.running()

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容