阮一峰大佬的JS(初识)面向对象(读书笔记)

阮一峰大佬的JS(初识)面向对象(读书笔记)
最新回答
不问归期

2026-02-21 07:03:01

阮一峰大佬的JS(初识)面向对象读书笔记,主要介绍了JavaScript中面向对象编程的核心概念,包括原型、构造函数、继承等。以下是对这些内容的详细总结:

  • 原型

    JavaScript中,每个创建的对象都会设置一个原型,指向它的原型对象。

    所有的函数对象都有一个原型对象(prototype)。

    所有的对象上都有一个隐式原型(__proto__)指向创建该对象的构造函数的原型。

    所有的原型上都有一个constructor指向该原型所在的构造函数本身。

  • 构造函数模式

    构造函数是普通函数,但内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

    示例:

    function Cat(name, color) { this.name = name; this.color = color;}var cat1 = new Cat("大毛", "黄色");var cat2 = new Cat("二毛", "黑色");alert(cat1.name); // 大毛alert(cat1.color); // 黄色

    弊端:如果所执行的方法都是一样的,但都要生成一个实例,就很占内存。

  • prototype模式

    每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的属性和方法,都会被构造函数的实例继承。

    为了解决构造函数占用重复内存的问题,可以将共有的属性和方法放在prototype对象上。

    示例:

    Cat.prototype.eat = function() { alert("吃老鼠") };cat1.eat == cat2.eat // true

    验证方法:

    isPrototypeOf():用来判断某个对象的原型与某个实例之间的关系。

    hasOwnProperty():用来判断某一个属性到底是本地属性,还是继承自prototype的属性。

    in运算符:用来判断实例对象是否含有某个属性,不管是不是本地属性还是继承属性;还可以用来遍历某个对象的所有属性。

  • 继承

    构造函数绑定:使用call、apply方法将父对象的构造函数绑定在子对象上。

    function Cat(name, age) { Animal.call(this, arguments); // 继承Animal this.name = name; this.age = age;}

    prototype模式:如果猫的prototype指向一个Animal实例,那么所有猫的实例都能继承Animal。

    Cat.prototype = new Animal();// 此时的Cat.prototype.constructor == Animal; cat1明明是用构造函数Cat生成的,因此我们必须手动矫正Cat.prototype.constructor = Cat;let cat1 = new Cat();

    直接继承

    Cat.prototype = Animal.prototype;Cat.prototype.constructor = Cat;但是改变Cat原型,Animal的原型也会改变,不可取。

    空对象继承:创建一个空的函数对象,将该函数对象的原型指向父对象的原型,然后删除了子对象prototype对象原先的值,赋予一个新值。

    var F = function() {};F.prototype = Parent.prototype;Child.prototype = new F();Child.prototype.constructor = Child;

    拷贝继承

    function extend2(Child, Parent) { var p = Parent.prototype; var c = Child.prototype; for (var i in p) { c[i] = p[i]; } c.uber = p;}

    浅拷贝与深拷贝

    浅拷贝:修改子对象会对父对象产生影响。

    function copy(p) { let c = {}; // 创建一个空对象(容器) for (let i in p) { // in运算符遍历属性与方法 c[i] = p[i] // 一一放入空对象 } return c // 返回空对象}Doctor = copy(Chinese);Doctor.bb.push(12);console.log(Chinese.bb); // 1,2,3,4,12console.log(Doctor.bb); // 1,2,3,4,12

    深拷贝:修改子对象不会对父对象产生影响。

    function copy2(p, c) { var c = c || {}; for (let i in p) { if (typeof p[i] === `object`) { c[i] = (p[i].constructor === Array) ? [] : {}; copy2(p[i], c[i]); } else { c[i] = p[i]; } } return c;}Doctor = copy2(Chinese);Doctor.bb.push(12);alert(Doctor.bb); // 1,2,3,4,12alert(Chinese.bb); // 1,2,3,4