JavaScript中的构造函数和原型

81 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

this

在全局作用域中, this指向window对象

在函数中, this指向windown对象

在方法中, this指向调用该方法的对象

在构造函数中, this指向新创建的对象

在使用call和apply方法调用函数时,this指向指定的对象

console.log('global: ' + this);// this是window       
        function func() {
            console.log(this);
        }

        func(); // this: 在这个函数中this是window对象

        func.call(); // this: window对象

        func.apply(); // this: window对象

        let person = {
            name: 'shaosiming',
            age: 18,
            sayHi: function() {
                console.log('我叫少司命');
                console.log(this); // {name: 'shaosiming', age: 18, sayHi: ƒ}age: 18name: "shaosiming"sayHi: ƒ ()[[Prototype]]: Object

            }
        }
        person.sayHi(); // this指向person1

        let person2 = {
            name: 'dasiming',
            age: 18,
            sayHi: function() {
                console.log('我叫大司命');
                console.log(this); // {name: 'dasiming', age: 18, sayHi: ƒ}
            }
        }
        person2.sayHi(); // this指向person2

        function Person() {
          console.log('Person: ' + this); // 在构造函数中this指向新创建的实例对象
        }

构造函数

构造函数是用来创建对象的函数

通过同一样构造函数创建的对象, 称之为一类对象, 也就是这样的对象的类都是这个构造函数的函数名

构造函数, 也是一函数, 只不过它是一个特殊的函数.

函数名首字母大写, 使用new关键字来调用, this在构造函数中表示新创建的对象

构造函数如果像普通函数那样调用, 那么它就是普通函数

        // 构造函数
        function Person(name, age) {
            this.name = name;
            this.age = age;
        }

        let p1 = new Person('shaosiming', 18);
        let p2 = {
            name: 'dasiming',
            age: 20
        }
        console.log(p1); // Person {name: 'shaosiming', age: 18}
        console.log(p2); // Object {name: 'shaosiming', age: 18}

instanceof

对象名 instanceof 构造函数名

如果该对象是构造函数的实例, 返回true, 否则返回false

Object对象相当于所有对象的基类, 因此所有对象 instanceof Object都返回true

        // instanceof
        console.log(p1 instanceof Person); // true
        console.log(p1 instanceof Object); // true
        console.log(p2 instanceof Person); // false
        console.log(p1 instanceof Object); // true

for...in语句

遍历对象中的所有属性

对象中属性的个数, 就是for...in语句循环的次数

        // 遍历对象中的属性
        for (const prop in p1) {
            console.log(prop + ':' + p1[prop]);
        }

原型对象

无论是函数还是构造函数, 它们内部都有一个隐藏的原型对象, 可以通过 函数名.prototype 来访问

通过构造函数创建的对象, 内部也有一个隐藏的原形对象, 可以通过 对象名.proto 来访问

注意: 通过构造函数创建的对象上的原型对象和构造函数上的原型对象是同一个原型对象

作用: 公共的属性和方法可以添加到原型对象上, 这样可以节省内存

原型链: 当我们说对象的属性或方法时, 先在对象自身查找; 如果没有查到, 则去原型对象中查找; 如果还是没找到, 再原型中的原型中查找, 依次查找, 最后找到Object上的原型对象, Object.prototype==null

        let p3 = new Person('xiaoshishu', 19)
        let p4 = new Person('ergouzi', 18)

        // 向原形对象上添加属性和方法
        Person.prototype.shareName = '这是原形对象上的name';
        p3.__proto__.shareHobby = '这是原形对象上的hobby';

        console.log(p4.__proto__.shareName);
        console.log(p4.__proto__.shareHobby);

        console.log(p3.__proto__ == p4.__proto__); // true
        console.log(p3.__proto__ == Person.prototype); // true
        console.log(p4.__proto__ == Person.prototype); // true

        // 向原型对象上添加方法
        Person.prototype.printInfo = function() {
            console.log('Person[name:"' + this.name + '", age:', this.age + ']');
        }

        // 通过构造函数创建的对象, 都可以直接调用该方法
        p3.printInfo();
        p4.printInfo();

hasOwnProperty('属性名')

属性名 in 对象名 对象自己的属性中和原型中能找到的话, 返回true, 否则返回false

对象名.hasOwnProperty('属性名') 只有对象自身中有y该属性的话, 才会返回true, 否则返回false

        console.log('name' in p3); // true
        console.log('shareName' in p3); // true
        console.log(p3.hasOwnProperty('name')); // true
        console.log(p3.hasOwnProperty('shareName')); // false