function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
}
};
let p = new Person('Ethan', 24, 'java')
console.log(p.name); // Ethan
构造函数实际上会经历以下 4 个步骤:
- 在内存创建一个新对象;
- 新对象的内部【prototype】特性被赋值为构造函数的prototype
- 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
- 执行构造函数中的代码(为这个新对象添加属性);
- 返回新对象。
函数表达式也可以是构造函数
```javascript let Person =function (name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function () { console.log(this.name); } };
let p = new Person(‘Ethan’, 24, ‘ java’)
console.log(p.name); // Ethan
**在实例化时 如果不想传参数,那么也可省略括号 只要有new操作符就可以**
```javascript
function Person(){
this.name = "gaojian"
this.sayName = function(){
console.log(this.name)
}
}
let person1 = new Person();
let person2 = new Person;
person1.name() //"gaojian"
person2.name() //"gaojian"
其实person1和person2 每个对象都是Object的实例 同事也是 Person的实例 用instanceof 可以查看结果
function Person(){
this.name = "gaojian"
this.sayName = function(){
console.log(this.name)
}
}
let person1 = new Person();
let person2 = new Person;
console.log(person1 instanceof Object); //true
console.log(person2 instanceof Object); //true
console.log(person1 instanceof Person); //true
console.log(person2 instanceof Person); //true
构造函数也是函数 与普通函数的区别
构造函数与普通函数的最大区别就是调用方式不同,任何函数只要使用new 操作符调用就是构造函数,而不用new调用就是普通函数。
区别:
- 调用方式“创建当前类的实例对象”
- 在构造函数中This指向这个实例对象 构造函数中this.xxx =xxx 都是给实例对象设置属性的私有属性和方法 自己单独声明的变量 和实例没有关系
- 如果构造函数中没有return 或返回的是原始类型,则把场景的实例对象返回,只有自己手动返回的对象,才以自己的返回值为主
作为构造函数
function Person(name, age) {
this.name = name || "gaojian";
this.age = age;
this.sayName = function () {
console.log(this.name + this.age)
}
}
let person1 = new Person("tom", 33);
let person2 = new Person('', 33)
person1.sayName()
person2.sayName()
作为函数调用
function Person(name, age) {
this.name = name || "gaojian";
this.age = age;
this.sayName = function () {
console.log(this.name + this.age)
}
}
Person("kill", 22) //此时添加到window对象上
window.sayName()
在另一个对象的作用域上调用
let obj = Object.create(null)
Person.call(obj,"hanmei",33)
obj.sayName() //hanmei33
构造函数的问题
主要问题在于 其定义的方法会在每个实例上都创建一遍 特别是函数 每次定义函数时 都会初始化一个对象 解决这个问题可以把函数转移到构造函数外部:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
};
function sayName() {
console.log(this.name);
}
let p = new Person('Ethan', 24, 'java');
p.sayName(); // Ethan
但这样做全局作用域也被搞乱了 而且对象如果有多个方法那都需要定义在全局作用域里 解决这个问题那就是需要原型模式 原型继承来解决
练习题(珠峰)
知识点:
- 每次new 都是创建单独的实例对象 f1 !== f2
- 在构造函数中This指向这个实例对象 构造函数中this.xxx =xxx 都是给实例对象设置属性的私有属性和方法 自己单独声明的变量 和实例没有关系
- 设置的私有属性,两个实例 即使同名属性 也都是自己私有的 f1.say !== f2.say
**
function Fn(x, y) {
let sum = 10;
this.total = x + y;
this.say = function () {
console.log(`我计算的和是:${this.total}`);
};
}
let res = Fn(10, 20); //普通函数执行
window.say()
let f1 = new Fn(10, 20); //构造函数执行
let f2 = new Fn;
console.log(f1.sum);
console.log(f1.total);
console.log(f1.say === f2.say);
**