构造函数 new class prototype

构造函数 new class prototype

个人笔记,欢迎友好交流讨论。如有错误,还望指正!

构造函数

构造函数也是一个函数,类似于

function Person(name) {
	// 代码   
}

有函数名(Person),也有参数(name)

构造函数与其他普通函数的区别在于:

  1. 构造函数习惯上 首字母大写

  2. 构造函数使用 new 关键词调用

  3. 构造函数内部用 this 来创建实例化对象的属性和方法

  4. 构造函数本身没有 return 返回值,使用 new 操作符会自动创建一个新对象,并将新对象作为返回值返回;普通函数没有 return ,会返回 undefined

  5. 构造函数的执行流程

    • 立刻在堆内存中创建一个新的对象
    • 将新建对象设置为函数中的 this
    • 执行函数中的代码
    • 将新建的对象作为返回值
// 给出一个构造函数的例子
function Person(name) {
    this.name = name;
    this.info = function() {
        console.log(this.name)
    }
}

var p = new Person("Jack")
console.log(p.name)		// "Jack"
p.info()				// "Jack"

new

使用 new 操作符 调用一个构造函数,发生了什么?

var obj = {}
obj.__proto__ = Person.prototype
Person.call(obj, name)	// 也可以使用 apply(), 主要根据参数情况选择,后文中选择 apply()
return obj

逐行解读:

  • 创建一个空对象 obj
  • 让空对象的 __proto__ 成员指向构造函数对象的 prototype
  • 调用 Person 函数,并让 Person 函数中的 this 指向为新创建的空对象
  • 返回新对象 obj

实现一个简单的 new 方法

// 定义构造函数
function Person(name, age) {
    this.name = name
    this.age = age
}
// 给构造函数添加 原型对象(该构造函数创建的实例化对象 
// 都可以 使用 Person.prototype 中的方法和属性)
Person.prototype.info = function () {
    console.log(this.name, this.age)
}

// 自己定义 new 方法
function myNew(Func, ...params) {
    let obj = {}
    obj.__proto__ = Func.prototype
    Func.call(obj, params)
    return obj
}

var p = myNew(Person, 'hyy', 22)

// 检验与 new 创建的效果是否相同
p instanceof Person	// true

// Person {name: "hyy", age: 22}
// 		age: 22
// 		name: "hyy"
// 		__proto__:
// 			info: ƒ ()
// 			constructor: ƒ Person(name, age)
//			__proto__: Object

class

接触过其他语言的同学应该会对 class 更加熟悉,我在最开始接触到 JS 中的面向对象时,没想到是用构造函数和原型链这些。

承接上文中的 Person 构造函数,将其用 class 改写,如下:

class Person {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    
    info() {
        console.log(this.name, this.age)
    }
}

var p = new Person('hyy', 22)
p instanceof Person	// true

接下来,对 class 的基本语法做简单解释:

  1. constructor 方法是 ES6 中类的默认方法,通过 new 命令生成对象实例时,会自动调用该方法,一个类必须有 constructor 方法,如果没有定义,一个空的 constructor 方法会被默认添加。

  2. 直接在类创建时,定义的方法,全部都定义在类的 prototype 上。如上面例子中的 info() 函数是定义在 Person 类的 prototype 原型对象上,通过 new 操作符生成的实例化对象可以调用 info() 函数。

  3. 给类添加静态方法或静态属性,在方法前加关键词 static ,表示该方法是类的静态方法,实例无法访问。例子:

    class Person {
    
        constructor(name, age) {
            this.name = name
            this.age = age
        }
    
        info() {
            console.log(this.name, this.age)
        }
    
    	static func() {
        	console.log('这是一个静态方法')
    	}
        static msg = '这是一个静态属性'
    }
    
    var p = new Person('hyy', 22)
    p.func	// undefined
    Person.func()	// "这是一个静态方法"
    

    补充,更多关于 class 语法内容,请移步参考资料

prototype

关于 prototype__proto__constructor 一些知识点总结:

  1. 我们需要牢记两点:

    __proto__constructor 属性是 对象 所独有的;

    prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有 __proto__constructor 属性;

    ③ 单从 constructor 属性来讲,只有 prototype 对象才有,但是其他被构造函数创建出来的对象可以通过原型链找到 这个属性。

  2. __proto__ 属性的 作用 就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的 __proto__ 属性所指向的那个对象(父对象)里找,一直找,直到 __proto__ 属性的终点 null ,再往上找就相当于在null上取值,会报错。通过 __proto__ 属性将对象连接起来的这条链路即 我们所谓的原型链

  3. prototype 属性的 作用 就是让该函数所实例化的对象们都可以找到公用的属性和方法,即 p.__proto__ === Person.prototype

  4. constructor 属性的含义就是 指向该对象的构造函数 ,所有函数(此时看成对象了)最终的构造函数都指向 Function

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript中的构造函数是用于创建对象的特殊函数。它们与普通函数的不同之处在于,它们使用“new”关键字来调用,从而创建一个新的对象。构造函数通常用于定义类(class),并在创建新对象时初始化类的属性和方法。下面是一些关于构造函数的详细说明: 1. 构造函数的命名通常以大写字母开头,以便与其他函数区分开来。 2. 构造函数内部使用“this”关键字来引用新创建的对象。 3. 构造函数使用“prototype”属性来定义对象的方法。 4. 构造函数可以接受参数,这些参数可以用来初始化对象的属性。 5. 构造函数可以使用“instanceof”操作符来确定一个对象是否为特定类的实例。 下面是一个简单的构造函数示例,它定义了一个名为“Person”的类,该类具有“name”和“age”属性: ```javascript function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old."); } var john = new Person("John", 30); john.sayHello(); // 输出:Hello, my name is John and I am 30 years old. ``` 在这个示例中,“Person”函数是一个构造函数,在创建新对象时使用“new”关键字来调用。该函数使用“this”关键字来引用新创建的对象,并将“name”和“age”属性分配给该对象。使用“prototype”属性,我们为“Person”类定义了一个“sayHello”方法,可以用来打印对象的属性。最后,我们创建了一个名为“john”的新对象,并调用了它的“sayHello”方法,输出了对象的属性。 希望这个简单的示例可以帮助你更好地理解构造函数的概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值