1.原型
1.1 prototype
原型prototype其实是function对象的一个属性,而prototype本身也是对象。
function Handphone(){}
console.log(Handphone.prototype);
- 这个prototype是定义构造函数出来的每个对象的公共祖先。
- 所有被该构造函数构造出来的对象都可以继承原型上的属性和方法。
// prototype 实际上是一个function 的属性
function Handphone(color, brand){
this.color = color;
this.brand = brand;
}
Handphone.prototype.rom = '64G';
Handphone.prototype.ram = '6G';
var phone1 = new Handphone('red', 'xiaomi');
var phone2 = new Handphone('black', 'iphone');
// console.log(Handphone.prototype);
console.log(phone1);
console.log(phone2);
console.log(phone1.rom);
console.log(phone2.ram);
1. 这个prototype是定义构造函数出来的每个对象的公共祖先。
2. 所有被该构造函数构造出来的对象都可以继承原型上的属性和方法。
function Handphone(color, brand){
this.color = color;
this.brand = brand;
}
Handphone.prototype.rom = '64G';
Handphone.prototype.ram = '6G';
Handphone.prototype.screen = '18:9';
Handphone.prototype.system = 'Android';
Handphone.prototype.call = function(){
console.log('I am calling somebody');
}
var hp1 = new Handphone('red', 'xiaomi');
var hp2 = new Handphone('Black', 'huawei');
hp1.call();
hp2.call();
公共部分的属性,方法,都可以写在prototype上来继承
function Handphone(color, brand){
this.color = color;
this.brand = brand;
}
Handphone.prototype = {
rom: '64G',
ram: '6G',
screen: '18:9',
system: 'Android',
call: function(){
console.log('I am calling somebody');
}
}
var hp1 = new Handphone('red', 'xiaomi');
var hp2 = new Handphone('Black', 'huawei');
hp1.call();
hp2.call();
1.2 constructor
constructor => 构造函数本身
- constructor是原型里的一个属性,它指向的是构造函数本身,因此所有被该构造函数实例化出来的对象,都可以继承原型上的方法和属性.
- constructor的指向可以被人修改 ```javascript function Handphone(color, brand, system){ this.color = color; this.brand = brand; this.system = system; }
function Telphone(){
}
Handphone.prototype = { constructor: Telphone }
var hp1 = new Handphone(‘red’, ‘xiaomi’, ‘Android’); console.log(hp1);
![image.png](https://cdn.nlark.com/yuque/0/2022/png/26116833/1645613808868-1380d102-5d0c-401d-a72f-8b9b30974230.png#clientId=u2c39abd6-3a0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=151&id=u60310d3f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=189&originWidth=1249&originalType=binary&ratio=1&rotation=0&showTitle=false&size=27052&status=done&style=none&taskId=u97c0f7c0-4be3-46b0-a54a-031790240aa&title=&width=999.2)
原型属于实例化对象,他不属于构造函数.在实例化之前prototype没有挂靠对象,所以原型挂靠构造函数. 而在实例化对象之后,原型挂靠实例化出来的对象
```javascript
function Car(){
// __proto__: 每个实例化对象原型的容器
// var this = { // 当构造函数被new实例化的时候
// __proto__: Car.prototype
// }
}
Car.prototype.name = 'Mazda';
var car = new Car();
// 1. new 首先创建一个全新的对象
// 2. 这个新对象会被执行[[prototype]] 连接
// 3. 这个新对象会被绑定到函数调用的this
// 4. 如果函数不返回新对象, 那么new 表达式中的函数调用会自动返回这个新对象.
console.log(car.name); // Mazda
console.log(car); // Car{}
1.3proto也可以被更改
function Person(){}
Person.prototype.name = '张三';
// Person.prototype ={
// }
var p1 = {
name: '李四'
}
var person = new Person();
console.log(person.name); // 张三
person.__proto__ = p1;
console.log(person.name); // 李四
在实例化之后给prototype重新赋值,只会保存在实例化对象下面的proto里面的constructor属性里面的proto中,只有重新实例化这个构造函数的时候,
constructor里面保存的值,才会被实例化出来.
因此在实例化之后给prototype重新赋值修改的是实例化之前constructor里面的值,当重新实例化这个构造函数的时候,constructor里面被重新赋的值就可以被访问.
function Car(){}
Car.prototype.name = 'Mazda';
var car = new Car();
Car.prototype.name = 'Benz';
console.log(car.name);// 'Benz'
function Car(){}
Car.prototype.name = 'Benz';
var car = new Car();
Car.prototype = {
name: 'Mazda';
}
console.log(car.name);// 'Benz'
// 实例化时的操作
Car.prototype.constructor => Car()
Car.prototype => {name: Benz}
function Car(){
var this = {
__proto__: Car.prototype = {
name: 'Benz'
}
}
}
2.闭包立即执行函数
2.1 return 和 window的区别
return
function test(){
var a = 1;
function plus1(){
a++;
console.log(a);
}
return plus1;
}
// 必须把值返回出去,赋值给别的变量
var plus = test();
plus(); // 2
plus(); // 3
window
function test(){
var a = 1;
function add(){
a++;
console.log(a);
}
window.add = add;
}
test();
add();
在使用立即执行函数的时候,用return返回值的时候,需要声明一个全局变量保存函数的返回值.
在使用立即执行函数的时候,用window可以把函数的返回值直接存储在window全局对象下. ```javascript var res = (function(){ var a = 1; function add(){a++;
console.log(a); } return add; })() res(); // 2 res(); // 3 res(); // 4
(function test(){ var a = 1; function add(){ a++; console.log(a); } window.add = add; })()
add();// 2 add();// 3
<a name="olUNH"></a>
# 3. JS插件
```javascript
;(function(){
function Test() {}
Test.prototype = {
}
window.Test = Test;
})()
var test = new Test();
4. 作业
任意传俩个数字,调用插件内部方法可进行加减乘除功能
// 方法1
;(function(){
function Compute(){}
Computer.prototype = {
plus: function(a, b){
return a + b;
},
min: function(a, b){
return a - b;
},
mul: function(a, b){
return a * b;
},
div: function(a, b){
return a / b;
}
}
window.Compute = Compute;
})()
var com = new Compute();
// 方法2
;(function(){
function Compute(opt){
this.num1 = opt.num1;
this.num2 = opt.num2;
}
Compute.prototype = {
plus: function(){
return this.num1 + this.num2;
},
min: function(){
return this.num1 - this.num2;
},
mul: function(){
return this.num1 * this.num2;
},
div: function(){
return this.num1 / this.num2;
}
}
window.Compute = Compute
})()
var com = new Compute({
num1: 1,
num2: 3
});
var res = com.mul();
console.log(res);