zoukankan      html  css  js  c++  java
  • javascript 面向对象基础 (1)

    一、常见的创建对象的方式有3种:

    ① 声明变量的方式

    var obj1 = { key1: "val1", key1: "val2", show: function () { console.log(this.key1) } }
    var array = [1, 2, 3];

    可以给 obj1 继续添加属性和方法,如:

    obj1.color = "red";
    obj1.hideen = function () { console.log("aaa") };

     使用操作符 new

    var obj2 = new Object();

    可以给 obj2 继续添加属性和方法,如:

    obj2.name = "madom";
    obj2.show = function () { console.log("aaa") };

    ③ 创建构造函数

    function Cat() {             
      this.age = "18";   this.show = function () {     console.log(this.age);   } }

    其实,构造函数 也是普通函数,只有当 new 操作的时候才是构造函数,

    通过构 造函数 创建实例对象。每一个对象都有自己的内部原型 proto_

    各个实例对象之间并不相同。

    var cat1 = new Cat(); 
    cat1.__proto__ === Cat.prototype; //true
    var cat2 = new Cat(); 
    cat2.__proto__ === Cat.prototype; //true 
    cat1 === cat2; // fals  

    再创建一个带有 return 的构造函数

    function Bird() {
        this.age = 19;
        this.say = function () { console.log('my age is ' + 19) };
        return {
            name: 'Tim',
            say: function () { console.log('hello ' + this.name) },
        };
    }

    创建一个对象实例,看看有什么不同

    var bird = new Bird();
    bird.say(); // hello Tim
    console.log(bird); // Object {name: "Tim", say: function}

    发现:如果构造函数有 return,则对象实例无法使用构造函数 return 之前的属性和方法

    new 操作时内部的运作大致如下:
    第1步: 在内存中开辟一块空间。
    第2步: 创建一个新空对象,并把 this 指向到这个空对象。
    第3步: 把空对象的 内部原型 指向 构造函数的 原型对象。
    第4步: 当构造函数执行完成后,如果 没有 return(返回值) 的话,
    则构造函数末尾存在 ‘隐式’ 的 return this;如果  return(返回值),则将返回值赋值给对象实例。

    对创建实例的操作做如下模拟(非真实执行):

    var cat = new Cat();
    /* this = { };
     * this._proto_ = Cat.prototype
     * this = cat;
     * return this
     */

    二、实例的属性、方法 和 构造函数的属性、方法


    每个实例都可以扩展自己的属性和方法

    var cat = new Cat();
    cat.sex = 'male';
    cat.sing= function () {
        console.log('喵...');
    };
    console.log(cat.sex); // male
    console.log(cat.sing()); // 喵...

    实例继承了构造函数的属性和方法,优先在 自身 找对应的属性和方法,没找到就到构 造函数 的 原型里 找;
    如果给实例添加了与构造函数 同名的 属性和方法,如下:则自动 屏蔽 构造函数里的属性和方法;

    var cat = new Cat();
    cat.age = 20;
    cat.show = function () {
        console.log('I am a cat !')
    };
    console.log(cat.age); // 20
    console.log(cat.show()); // I am a cat !

    所以,建议 在原型里存公共的属性,常量,方法,对象实例会 共用 原型中的属性,常量,方法,这样可以节约内存的开销

    function Dog( ) {
        this.age = 2;
        this.name = 'Tom';
    }
    Dog.prototype.show = function() {
        console.log(this.age);
    }

    除了给对象实例扩展属性和方法,也可以给构造函数扩展属性和方法,当然也可以改写其属性和方法(对 js 内置对象的属性方法的修改需谨慎)

    Dog.prototype.weight = "3kg"; // 增加属性
    Dog.prototype.age = 99; // 修改属性
    // 增加方法,修改方法同上

    构造函数的用途就如工厂,输入对应的原材料,即可输出产品

    // 创建“工厂”
    function Dog( option ) {
        this.age = option.age;
        this.name = option.name;
    }
    Dog.prototype.show = function() {
        console.log(this.name + ':' + this.age);
    }
    // 准备“材料”
    var option1 = {
        name: "Hapa",
        age: 18
    }
    // 输出“产品”
    var dog1 = new Dog(option1);
    dog1.show(); // Hapa:18

    构造函数的一种“流行”的写法(构造函数上只有函数调用,原型上写属性和方法)

    Dog.prototype = {
        _init: function ( option ) {
            this.age = option.age || 3; // 如果 option 中没有属性 age,则默认 3
            this.name = option.name || 'Bob'; // 如果 option 中没有属性 name ,则默认 "Bob"
        },
        show: function () {
            console.log(this.age);
        },
        sing: function () {
        console.log('汪...');
      } };

    三、this 的指向,函数的四种调用模式


    ① 函数执行模式 

    // 定义一个加法函数
    function add(a, b) {
        console.log(this === window); // true
        return a + b;
    }
    // 调用此函数
    add(1, 1);  // 2

    可以看出,函数执行模式中,this 指向 window。(其实 window.add(1, 1); 也是可以调用的,本质上也是对象方法调用模式)

    ② 对象方法调用模式

    document.onclick = function () {
            console.log(this === document); // true
    }

    所有的事件响应方法都是对象方法调用模式,在此不再列举了, dog.sing();中 this 指向 dog 这个实例,它们有个共同点,就是  "xxx.yyy()" 的格式

    ③ 构造器的调用模式 

    // 构造函数
    function Dog() {
        this.age = 3;
        this.show = function () {  
           console.log(Object.prototype.toString.call(this)); 
        }
    }
    // 实例化一个 dog 对象
    var dog = new Dog(); 
    dog.show(); // [object Object]
    console.log(Object.prototype.toString.call(Dog)); // [object Function]

    dog 调用 show 方法时,打印出 this 是 一个 Object 对象,而 构造函数 Dog 打印出来是个 Function,所以 this 不是指向 Dogthis 的属性和方法对象实例 dog 都有,说明...

    额~还没想好怎么证明 this 就是 dog ...

    --- 知识在于分享,转载请注出处 ---

  • 相关阅读:
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言II博客作业04
    C语言II博客作业03
    C语言II博客作业02
    C语言II博客作业01
    期末总结
    第一次作业
    C语言I博客作业08
  • 原文地址:https://www.cnblogs.com/cokid/p/6883632.html
Copyright © 2011-2022 走看看