zoukankan      html  css  js  c++  java
  • javaScript 的对象创建

      最近开始接触js,语法什么的都还行,唯独对于面向对象这一块的概念一直比较模糊,晚上的资料也都对照的看了看,总结了一下自己的理解。

      在传统的面向对象的语言如java中,都会有一个class类,class不是对象,它可以理解为是一张图纸。根据这些图纸创建的实例才是可以调用的对象。比方说我们有个锤子图纸,它有锤人的功能。我们只有把这个锤子按照图纸造出来,才能拿来锤人,要不然你拿个图纸去锤人,会被反杀的。

      但是在js的世界里面,没有图纸的概念,一切都是对象。可以理解为js对象就是一堆属性和方法的集合。下面就是一个简单的对象。

    var Student = {
         name:'zhangsan',
         age:13,
         say:function(){
             console.log('my name is '+this.name + ', I am'+this.age+'years old!');
         }
        
    }

      但是这种方法比较麻烦,如果每次创建对象我们都要用这种方式来构建,那就很坑爹了。你可以封装一个函数,传入name和age,函数来帮你构建,如下

    function Student(name,age){
         return {
         name:name,
         age:age,
         say:function(){
             console.log('my name is '+this.name + ', I am'+this.age+'years old!');
             }
        }    
    }

      这种方式也可以,但是这个对象每次都会开辟新的内存空间,比较不环保。上面两个方式完全没有面向对象编程的感觉,感觉还是面向函数式编程的样子,我们下面来了解下另外一种创建对象的方法《构造函数模式》。

      先看一个简单的栗子

    function Student(name,age){
    this.name = name;
    this.age = age;
    this.say = function(){
      console.log('my name is '+this.name + ', I am'+this.age+'years old!');
    } }
    
    var zhangsan = new Student('zhangsan',13);
    
    zhangsan.say();

      到这一步已经有点面向对象的意思了,但是依旧没有解决上面栗子中的内存开销问题。这个时候我们需要了解js中另外一个东西,同时结构一下,new 函数的整个过程。

       JavaScript中没有类的概念,但是JavaScript中有一个原型的概念prototype。当已存在一个对象的时候,可以通过指定对象的prototype的方法来,来依据已存在的对象创建新的对象。有点绕,直接上代码。

    var Student = {
         name:'zhangsan',
         age:13,
         say:function(){
             console.log('my name is '+this.name + ', I am'+this.age+'years old!');
         }
    }
    
    var Student2 = {name:'lisi'}
    Student2.__proto__=Student
    Student2.say()

      上面代码中,我们首先有了Student对象,再创建Student2对象,同时指定Student2对象的__proto__属性继承Student对象的age 和 say属性,name其实也继承了只是被重写了。

      这就是javaScript中的原型的概念,其实说白了就是当我们调用对象的属性和方法的时候,首先会调用自己的属性方法,当没有找到的时候就会到__proto__中去找有没有相关的属性和方法。

      每个对象都有自己的原型链,比如我们定义了一个数组类型arr = [],那么它的原型链就是arr ---->Array.prototype---->Object.prototype---->null。

      其实基本上和java的继承类似,那么我们再返回上面的构造函数模式中,创建对象的全过程,我们先看看伪代码

    var obj = {}
    obj.__proto__ = Student.prototype
    Student.apply(obj, arguments)
    return obj

      第一行代码是创建一个空对象。

      第二行是将空对象的原型属性指向构造函数Student的prototype属性,在这里要声明一下,在javaScript的规定里面,每个构造函数都有一个prototype属性。

      第三行的代码就是将构造函数的作用域赋予给对新对象,将构造函数中的this指向新对象。

      第四行返回对象

      通过上面的过程我们大致理解了构造函数创建过程,这个时候我们再思考一下前面的问题,关于对象创建时,重复创建函数的问题。我们可以对构造函数的prototype属性进行赋值,使所有的对象都指向同一个构造函数的prototype属性,这样我们就可以解决之前内存不环保的问题,这就表示我们可以把一些不变的方法或者属性定义在prototype属性上,下面我们上代码

    function Student(name,age){
    this.name = name;
    this.age = age;
    }
    
    Student.prototype.say = function(){
      console.log('my name is '+this.name + ', I am'+this.age+'years old!');
    } 
    student = new Student()
    student.say()

    其实本质上来讲,javascript面向对象的思想和别的语言差不多,只是因为没有使用class所以理解上有点别扭,但是从es6开始,javascript开始支持class关键字,我们可以像使用java一样来创建class,再根据class来new出对象来。但是为啥现在没有流行起来,我看到一些资料是说有些浏览器不支持es6,很多主流项目也没有引入class,如果要改的话,重构的工作应该也比较大。

  • 相关阅读:
    2018 秋招找工作总结
    Java 实现 LRU 缓存
    历时2个月,星云链DApp开发总结
    Java 版快速排序 + 最挫的优化
    MacOS 下防止 rm 命令误删
    Java使用Log日志系统(common-logging和log4j)
    IDEA+Maven+Spring+SpringMVC+SpringJDBC整合Demo
    Java简单实现并发编程
    设计模式学习笔记——单例模式
    Java获取网页内容
  • 原文地址:https://www.cnblogs.com/rubeitang/p/7687697.html
Copyright © 2011-2022 走看看