zoukankan      html  css  js  c++  java
  • js学习之面向对象

    一、创建对象的方法


    1、 {} 字面量创建

            var person ={
                name: "lisi",
                age: 21,
                say: function(){
                    alert(this.name);
                }
            };


    2、 new Object()

    var person = new Object();
    person.name = "lisi";
    person.age = 21;
    person.family = ["lida","lier","wangwu"];
    person.say = function(){
           alert(this.name);
    }

    3: 用构造函数创建

    function Person(name,age,family) {
        this.name = name;
        this.age = age;
        this.family = family;
        this.say = function(){
            alert(this.name);
        }
    }
    var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
    var person2 = new Person("lisi",21,["lida","lier","lisi"]);
    console.log(person1 instanceof Object); //true
    console.log(person1 instanceof Person); //true
    console.log(person2 instanceof Object); //true
    console.log(person2 instanceof Person); //trueconsole.log(person1.constructor);      //constructor 属性返回对创建此对象的数组、函数的引用


    4:Object.create方法创建
    创建完的对象有2个特点
    1、 可以添加属性 (属性的值为非函数的任意数据类型)
    2、 添加方法

    const person = {
        isHuman: false,
        say: function () {
            console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
        }
    };
    
    const me = Object.create(person); //使用现有的对象来提供新创建的对象的__proto__

    5、工厂模式

    function createPerson(name,age,family) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.family = family;
        o.say = function(){
            alert(this.name);
        }
        return o;
    }
    
    var person1 =  createPerson("lisi",21,["lida","lier","wangwu"]);   //instanceof无法判断它是谁的实例,只能判断他是对象,构造函数都可以判断出
    var person2 =  createPerson("wangwu",18,["lida","lier","lisi"]);console.log(person1 instanceof Object); //true

    6、原型模式

    function Person() {}
    
    Person.prototype.name = "lisi";
    Person.prototype.age = 21;
    Person.prototype.family = ["lida","lier","wangwu"];
    Person.prototype.say = function(){
        alert(this.name);
    };
    console.log(Person.prototype);   //Object{name: 'lisi', age: 21, family: Array[3]}
    
    var person1 = new Person();        //创建一个实例person1
    console.log(person1.name);        //lisi
    
    var person2 = new Person();        //创建实例person2
    person2.name = "wangwu";
    person2.family = ["lida","lier","lisi"];P9
    console.log(person2);            //Person {name: "wangwu", family: Array[3]}
    // console.log(person2.prototype.name);         //报错
    console.log(person2.age);              //21

    7、混合模式(构造函数模式+原型模式)

    构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性
    function Person(name,age,family){
        this.name = name;
        this.age = age;
        this.family = family;
    }
    
    Person.prototype = {
        constructor: Person,  //每个函数都有prototype属性,指向该函数原型对象,原型对象都有constructor属性,这是一个指向prototype属性所在函数的指针
        say: function(){
            alert(this.name);
        }
    }
    
    var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
    console.log(person1);
    var person2 = new Person("wangwu",21,["lida","lier","lisi"]);
    console.log(person2);


    new的工作原理


      通过new创建对象经历4个步骤

      1、创建一个新对象;[var o = {};] //创建一个空对象obj,然后把这个空对象的__proto__设置为Person.prototype(即构造函数的prototype);

      2、将构造函数的作用域赋给新对象 (因此this指向了这个新对象);[Person.apply(o)] [Person原来的this指向的是window]

      3、执行构造函数中的代码(为这个新对象添加属性);

      4、返回新对象

      // 1)创建一个新的对象;
      // 2)将构造函数的 this 指向这个新对象;
      // 3)为这个对象添加属性、方法等;
      // 4)最终返回新对象。

    什么是面向对象编程(OOP)?

    面向过程与面向对象
      1)面向过程:面向过程专注于如何去解决一个问题的过程步骤。编程特点是由一个个函数去实现每一步的过程步骤,没有类和对象的概念。
      2)面向对象:专注于由哪一个对象来解决这个问题,编程特点是出现了一个类,从类中拿到对象,由这个对象去解决具体问题。 对于调用者来说,面向过程需要调用者自己去实现各种函数。而面向对象,只需要告诉调用者,对象中具体方法的功能,而不需要调用者了解方法中的实现细节。

      

    面向对象的三大特征

      面向对象的三大特征是继承封装多态。JS可以模拟实现继承和封装,但是无法模拟实现多态,所以我们说JS是一门基于对象的语言,而非是面向对象的语言。

      封装:封装就是指利用抽象数据类型将数据和基于数据的操作封装在一起,数据被保护在抽象类型的内部,系统的其他部分只有通过包裹在数据外面的被授权的操作,才能够与这个抽象数据类型交流与交互!

      继承:继承实际上是存在于面向对象程序中的两个类之间的关系。当一个类拥有另一个类的所有数据和操作时,就称这两个类之间具有继承关系!

      多态:多态是指一个程序中同名的不同方法共存的情况。面向对象的程序中多态的情况有多种,可以通过子类对父类方法的覆盖实现多态,也可以利用重载在同一个类中定义多个同名的不同方法!
     

      1、封装

       什么是Js封装,就是当你需要隐藏一些属性和方法是,就可以将这些属性和方法封装起来,然后通过一个外部可以调用的特定接口(也可以说是一个公共的方法)进行调用。

      2、继承
        原型,原型链

      3、多态
        多态是指一个程序中同名的不同方法共存的情况。

      

    function Person(name, age, sex) {
        this.name = name; //共有变量 
        var age = age; //私有变量
        var sex = sex; //私有变量
        this.show = function () {
            console.log(age + "====" + sex);
        }
    }
    var person = new Person('Sunshine', 18, ''); console.log(person.age); // undefined console.log(person.name); // Sunshine console.log(person.show()); // 18====女

      注:this指向的都是共有的属性和方法,而直接通过var声明的则属于私有变量(即外部不可访问变量),然后通过一个共有的show方法将私有的age和sex输出。当然show方法也要通过this声明才可以哟,否则的话show方法也是不可访问的。

    类和对象
    1、:一类具有相同特征(属性)和行为(方法)的集合。
    比如,人类具有身高、体重等属性,吃饭、大笑等行为,所以,我们可以把人划分为一类。


    2、对象:从类中,拿出具有确定属性值和方法的个体。
    比如,张三-->属性:身高180体重180 方法:说话-->我叫张三,身高180

    3、类和对象的关系

    ①类是抽象的,对象是具体的(类是对象的抽象化,对象是类的具体化)

    ②类是一个抽象的概念,只能说类有属性和方法,但是不能给属性赋具体的。比如,人类有姓名,但是不能说人类的姓名叫什么。
      对象是一个具体的个例,是将类中的属性进行具体赋值而来的个体。
      比如,张三是一个人类的个体。可以说张三的姓名叫张三。也就是张三对人类的每一个属性进行了具体的赋值,那么张三就是由人类产生的一个对象。

    4、使用类和对象的步骤:
    1)创建一个类(构造函数):类名必须使用大驼峰法则。即每个单词首字母都要大写

    function 类名(属性1){
        this.属性1=属性1;
        this.方法=function(){
        //方法中要调用自身属性,必须使用this.属性
        }
    }


    2)通过类实例化(new)出一个对象。

    var obj=new 类名(属性1的具体值);
    obj.属性; 调用属性
    obj.方法; 调用方法


    3)注意事项:
    ①通过类名,new出一个对象的过程,叫做"类的实例化"。
    ②类中的this,会在实例化的时候,指向新new出的对象。
      所以,this.属性 this.方法实际上是将属性和方法绑定在即将new出的对象上面。
    ③在类中,要调用自身属性,必须使用this.属性名。如果直接使用变量名,则无法访问对应的属性。

    function Person(name,age){
        this.name=name;
        this.age=age;
        this.say=function(content){
            //在类中,访问类自身的属性,必须使用this.属性调用。
            alert("我叫"+this.name+",今年"+this.age+"岁,我说了一句话:"+content);
        }
    }
    var zhangsan=new Person("姐姐",18);
    zhangsan.say("你好呀");

    类名必须使用大驼峰法则,注意与普通函数区分。

    面向对象的两个重要属性

    1)constructor:返回当前对象的构造函数。

    2)instanceof:检测一个对象是不是一个类的实例;

    >>>lisi instanceof Person          //true √ lisi是通过Person类new出的
    >>>lisi instanceof Object          //true √ 所有对象都是Object的实例
    >>>Person instanceof Object        //true √ 函数本身也是对象


    成员属性、静态属性和私有属性
    1、在构造函数中,使用this.属性声明。或者在实例化出对象以后,使用"对象.属性"追加的,都属于"成员属性或成员方法"。也叫"实例属性或实例方法"。
      成员属性/方法,是属于由类new出的对象的。
      需要使用"对象名.属性名"调用。

    【静态属性与静态方法】
    2、通过“类名.属性名”、“类名.方法名”声明的属性和方法,称为静态属性、静态方法。也叫类属性和类方法。
      类属性/类方法,是属于类的(属于构造函数的)
      通过"类名.属性名"调用。

    3、成员属性是属于实例化出的对象的,只能使用对象调用。
      静态属性是属于构造函数的,只能使用类名调用。

    [私有属性和私有方法]


    4、在构造函数中,使用var声明的变量称为私有属性;
      在构造函数中,使用function声明的函数,称为私有方法;

    function Person(){
        var num=1;//私有属性
        function func(){}//私有方法
    }

    私有属性和私有方法的作用域,只在构造函数内容有效。即只能在构造函数内部使用,在构造函数外部,无论使用对象名还是类名都无法调用。

    JavaScript中的this指向详解

    1、谁最终调用函数,this最终指向谁(记住!)

    ①this指向谁,不应考虑函数在哪声明,而应该考虑函数在哪调用!!!
    ②this指向的永远只可能是对象,而不可能是函数。
    ③this指向的对象,叫做函数的上下文context,也叫函数的调用者。


    2、this指向的规律!!!(跟函数的调用方式息息相关,记住这点,相信你一定会分清this指向哒)
    ①通过函数名()调用的,this永远指向window
    ②通过对象.方法调用的,this指向这个对象。
    ③函数作为数组中的一个元素,用数组下标调用的,this指向这个数组
    ④函数作为window内置函数的回调函数使用,this指向window。 setInterval setTimeout 等。
    ⑤函数作为构造函数,使用new关键字调用,this指向新new出的对象。

    var fullname = 'John Doe';
    var obj = {
        fullname: 'Colin Ihrig',
        prop: {
            fullname: 'Aurelio De Rosa',
            getFullname: function () {
                return this.fullname;
            }
        }
    };
    
    console.log(obj.prop.getFullname()); //Aurelio De Rosa
    // 函数的最终调用者 obj.prop 
    
    var test = obj.prop.getFullname;
    console.log(test()); //John Doe
    // 函数的最终调用者 test()  this-> window
    
    obj.func = obj.prop.getFullname;
    console.log(obj.func()); //Colin Ihrig
    // 函数最终调用者是obj
    
    var arr = [obj.prop.getFullname, 1, 2];
    arr.fullname = "JiangHao";  //JiangHao
    console.log(arr[0]()); // 函数最终调用者数组

    class 与构造函数的区别?

      构造函数

    function Circle (x, y, r, color) {
            this.x = x
            this.y = y
            this.r = r
            this.color = color
          }
     
          Circle.prototype.render = function () {
            ctx.beginPath()
            ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, true)
            ctx.fillStyle = this.color
            ctx.fill()
          }
     
          Circle.prototype.update = function () {
            this.x += 1
          }

      class

    class Circle {
            constructor (x, y, r, color) {
              this.x = x
              this.y = y
              this.r = r
              this.color = color
            }
            render () {
              ctx.beginPath()
              ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, true)
              ctx.fillStyle = this.color
              ctx.fill()
            }
            update () {
              this.x += 1
            }
          }
  • 相关阅读:
    Google官方教程之Selling In-app Products
    In-app Billing 概述
    Android SDK和ADT无法更新的解决办法
    在NGUI中高效优化UIScrollView之UIWrapContent的简介以及使用
    cocos2d-x 3.1 编译脚本android-build.py
    Storm---DirectGroup(直接分组)
    Lucene Spatial构建地理空间索引
    Log4j2日志配置
    Guava缓存使用
    Maven 多套环境配置
  • 原文地址:https://www.cnblogs.com/zjz666/p/11349226.html
Copyright © 2011-2022 走看看