原型、原型链之间的关系
*原型(prototype) 原型链(__proto__)
*所有的函数数据类型天生自带 原型(prototype)属性,而她的属性值就是一个对象,存贮的还是共有的属性和方法。
*每个对象都有一个 原型链(__proto__)属性,而她指向当前实例所属类的原型(prototype),若不确定就是object实例。
*浏览器 ‘默认’ 给原型开辟的堆内存中,有一个constructor,存储的是当前类本身。
面向对象概念:
面向对象、面向过程:
都是一种编程思想。
js中的面向对象:
类----实例 每个类都对应一个实例 就像是(人类-->特朗普)
js中的一些内置类:
数组类Array 数字类Number 对象类Object 日期类Date 正则类RegExp ...
js中常见的设计模式:
* 单例模式:其实就是一个对象,我们把这个对象那个称为 ‘命名空间’
var per1={
name:'可爱'
age:18
eat:function(){
console.log(`${this.name}吃吃吃`)
}
}
var per2={
name:'可爱2'
age:22
}
var f= per1;
f();
==========================================
var tools={ //tools、 utils工具库
f1:function(){
},
f2:function(){
},
f3(){
},
}
tools.f1();//这就是说,封装了一个工具库,在用的时候直接调用就可以了
========================================================================
* 高级单例模式:
var utils=function(){
var name ='mingtian';
var sex='man'
var eat =function(){
console.log(`${this.name}吃吃吃`)
}
return {
name,sex,eat
}
}
var per3 = utils();//per3任然是个对象,
console.log(per3.name,per1.name)
per1.name='red'
per1.eat =functuion(){
console.log('ear apple')
}
per1.eat();
//普通单例,是没有私有的内容的。别的人员可以任意更改你的内部属性
per3.name='xiao hong';
//只是修改了per3这个对象中的name属性,并没有改变utils中的name变量
var per4=utils();
//高级单例模式,使用这个单例的人,是改变了不了内部变量的。
console.log(per4.name)
per1的name属性,用的人能否更改?
per3的name属性,用的人能否更改?
都是可以更改的,
====================================
* 工厂模式:就是一个普通的函数,适用于那些批量生产单例的情况。
var per1={
name:'xiaoming';
eat:function(){
console.log(`${this.name}吃饱了`)
}
smile(){
console.log(`${this.name}开心了`)
}
}
var factory = function(name,eat){
return{
name,
eat:function(){
console.log(`${this.name}吃`)
}
smile(){
console.log(`${this.name}笑`)
}
}
}
var per3=factory('three',111);
//per1是通过普通单例创造的,而per3就是通过工厂创造的。
==========================================
* 构造函数模式:这里的函数名约定是大写!(F)。
new执行函数的时候,会在变量提升之后,多了一步开辟堆内存,把this指向该堆内存,代码执行完成之后,默认返回this
var F = function(name){
this.name=name;
this.eat=function(){
console.log(`${this.eat}吃饱了吗`)
}
// return 123 构造函数,若return的是一个值类型,则不影响new的执行结果
// return [] 若返回的是一个引用数据类型,就会覆盖new的执行结果
}
var per4=new F('four');
//new执行函数的时候,**开辟作用域,形参赋值,变量提升**,然后把函数中的this指向了一个新开辟的堆内存。。然后在这之后,在操作this,其实就是在操作这个堆内存。最后,把this返出来。
console.log(per4);
========= ===== ===== ===== ======= ====== ===========
构造函数模式和工厂模式之间的区别? 构造函数模式: 不需要自己创造一个对象 不需要自己主动return内容 构造函数模式比构造函数模式多了一个原型 原型是每个函数都有的默认属性,对应的值是一个对象
=========================================
* 原型模式:prototype
每一个(对象)实例都有一个__proto__的实例,指向所属类的原型;Person.prototype
每一个(函数)类都有一个prototype的属性,指向自己的原型(prototype)
每一个类的原型上都有一个constructor属性,指向所有类(函数)本身。
var f = function(){
console.log(66);
}
console.log(f.prototype);
var ary=[]; //字面量的创建方式
var ary2=new Array(); //通过构造函数模式创建
ary.push(1,2,3);
ary2.push(5,6,7);
console.log(ary,ary2);
// Array ary2 ary都是Array是的实例
var Person= function(name,age){
this.name=name;
this.age=age;
this.eat=function(){
console.log(`${this.eat}吃饱了吗`)
}
}
Person.prototype.play=function(){
console.log('paly')
//在Person类的原型上添加一个play属性,值是一个函数
}
var per5=new Person('li',30);
var per6=new Person('zhu',20);
//per5 就是Person类的一个实例(就相当于一个对象),Person是一个自定义类
console.log(per5.paly===per6.paly);//true
console.log(per5.eat===per6.eat); //false
== ==== === ==== ===== ===== ===== ===== =======
- 作用域链:变量的查找机制,先看变量是不是自己私有的,不是的话就去上级作用域查找
- 原型链:对象中属性的查找机制,先在自己身上查找,没有的话就通过(原型链)——proto——向自己所属类的原型(prototype)上查找,原型上没有的话,就在通过原型链——proto——向上级原型查找,一直找到基类的原型,有的话就是返回值,没有的话就是undefined。
=========================================
* 原型:
function Person(name,age){
this.name = name;
this.age=age;
}
// 吃喝玩都是属于所有人类的共用属性,把这些共用属性都放到了原型上,(一生只放一次就够了)
Person.prototype.eat =function(){
console.log('eat')
}
Person.prototype.drink =function(){
console.log('drink')
}
Person.prototype.play =function(){
console.log('paly')
}
var per9 = new Person('lily',119);
var per0 = new Person('lucky',120);
per0.paly();
per9.eat();
function mypush(ary,...res){
for(var i =0;i<res.length;i++){
ary.push(res[i])
}
}
var ary =[1,2,3,4];
Array.prototype.mypush=function(){
console.log(this)
for(var i =0;i<res.length;i++){
this.push(res[i])
}
}
ary.mypush(4,5,6);
console.log(ary);