JavaScript基础10. 原型、插件开发

10.1原型

什么是原型

  1. 原型prototype其实是 function 对象的一个属性,结果它也是对象
function Handphone(){
  
}
console.log(Handphone.prototype);//{constuctor: f}
  1. 这个 prototype 是定义构造函数构造出的每个对象的公共祖先,所有被该构造函数构造出的对象都可以继承原型上的属性和方法
  2. 自己有的属性,就不会再去原型上去找
function Handphone(color, brand){
  this.color = color;
  this.brand = brand;
  this.screen = '18:9';
  this.system = 'Android';
}

Handphone.prototype.rom = '64G';
Handphone.prototype.ram = '6G';
Handphone.prototype.screen = '16:9';

var hp1 = new Handphone('red', '小米');
var hp2 = new Handphone('black', '华为');

console.log(hp1.rom);//64G
console.log(hp2.ram);//6G
console.log(hp1.screen); // 18:9

为什么所有的方法都写到原型上,为什么只有部分属性会写到函数内部?

  1. 在实例化的时候,总有些写死的值,每次 new 的时候,都要走一遍流程,属于代码的冗余。
  2. 因为属性往往都是配置项,而方法都是一样的,所以通用的属性和方法会写到原型上,需要动态改变的属性才放在构造函数上写

通过构造出来的实例对原型的增删改查

通过实例化对象增删改祖先prototype上的东西是不可行的

function Test() {
}

Test.prototype.name = 'prototype';

var test = new Test();

// 查
console.log(test.name);

// 添加
test.num = 1;
// 构造出来的对象添加东西不可行,不会增加到prototype上
console.log(Test.prototype, test);

// 删除,也影响不了prototype,删除的是实例化出来的对象自身的
delete test.name;
console.log(Test.prototype, test);

// 修改, 不可行
test.name = 'proto';
console.log(Test.prototype, test);

以对象的方式给原型赋值

function Handphone(color, brand, system){
  this.color = color;
  this.brand = brand;
  this.system = system;
}

Handphone.prototype = {
  rom: '64G',
  ram: '6G',
  screen: '18:9',
  call: function(){
    console.log('I am calling somebody');
  }
};

var hp1 = new Handphone('red', 'iphone', 'IOS');
console.log(hp1);
console.log(hp1.constructor);

image.png

consturctor 指向的是构造函数本身

    function Handphone(color, brand, system){
        this.color = color;
        this.brand = brand;
        this.system = system;
    }
    
    console.log(Handphone.prototype);

image.png

通过构造函数.prototype里面的constructor可改变构造器指向

function Telphone() {}
function Handphone(color, brand, system){
  this.color = color;
  this.brand = brand;
  this.system = system;
}
Handphone.prototype = {
  constructor: Telphone
}
console.log(Handphone.prototype); 

image.png

function Car() {
  // 隐式的 var this = {}; // 这个this指的就是实例化对象 car
  // proto 是实例化以后,属于的是对象实例,如果没有实例化,不存在proto,不属于构造函数
  // __proto__ 就是装 prototype 的容器,就是为了给 prototype 定义一个键名
}

Car.prototype.name = 'Benz';
var car = new Car();
console.log(car); // proto是实例化以后的结果

image.png

为什么能访问到car.name
this自身没有,找到__proto__,然后访问__proto__对应的prototype
proto属于每一个实例化的对象,而不是属于某个构造函数

总结:
当构造函数被new实例化的时候,产生了 this, this中默认给了__proto__装了实例化之后的原型,prototype没被额外赋值时,默认有constructor,constructor构造器默认指向构造函数本身,构造器构造出来的是Car的实例

__proto__是一个属性,属性值可以修改

function Person() {
  
}
Person.prototype.name = '张三';
var p1 = {
  name: '李四'
}

var person = new Person();
console.log(person.name); // 张三
person.__proto__ = p1;
console.log(person.name); // 李四
//person.__proto__  === Person.prototype 

给prototype属性赋值

function Car(){}
Car.prototype.name = 'Mazda';
var car = new Car();
// 给属性赋值
Car.prototype.name = 'Benz';
console.log(car.name); // Benz

重写prototype

Car.prototype.name = 'Benz';

function Car(){}

var car = new Car();

// 重写 prototype 
Car.prototype = {
  name: 'Mazda'
}; // 重写 prototype 是在实例化之后写的,没有实例化,修改的是实例化之前的prototype, 实例化之前的prototype保存在constructor所对应的构造函数的prototype中

console.log(car.name); // Benz

重写 prototype 是在实例化之后写的,没有实例化,修改无效 constructor
中保存的是实例化之前的东西,实例化之后就变成了对象

image.png

10.2插件开发

window return

function test() {
  var a = 1;
  function plus1(){
    a++;
    console.log(a);
  }
  return plus1;
}

var plus = test(); // 相当于 plus1 变成了全局函数
plus();
plus();
plus();
// 2 3 4
function test() {
  var a = 1;
  function add(){
    a++;
    console.log(a);
  }
  window.add = add; // 也形成了闭包
}

test();
add();
add();
add();
// 2 3 4
var add = (function(){
  var a = 1;
  function add(){
    a++;
    console.log(a);
  }
  return add;
})();
add();
add();
add();
// 2 3 4

(function(){
  var a = 1;
  function add(){
    a++;
    console.log(a);
  }
  window.add = add;
})();
add();
add();
add();
// 2 3 4

两个方法功能相同

js插件

(function(){ // 防止变量污染、函数作用域污染、隔离全局作用域
  function Test(){
    
  }
  Test.prototype = {}
  window.Test = Test;
})();

var test = new Test();

写立即执行函数默认先打一个分号,要不然两个立即函数一起会报错

;(function(){})()
;(function(){})()

应用

;(function(){
  var Compute = function(opt){
  }
  
  Compute.prototype = {
    plus: function(n1, n2){
      console.log(n1 + n2);
    },
    minus: function(n1, n2){
      console.log(n1 - n2);
    },
    mul: function(n1, n2){
      console.log(n1 * n2);
    },
    div: function(n1, n2){
      console.log(n1 / n2);
    }
  }
  
  window.Compute = Compute;
})();

var compute = new Compute();
compute.plus(2, 3);
compute.minus(7, 3);
compute.mul(4, 3);
compute.div(9, 3);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值