JavaScript提高篇之面向对象之单利模式工厂模型构造函数原型链模式

时间:2023-03-10 03:12:50
JavaScript提高篇之面向对象之单利模式工厂模型构造函数原型链模式

1.单例模式

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>面向对象之单例模式</title>
</head>
<body> <script type="text/javascript">
//对象数据类型的作用:
//把描述同一个事物(同一个对象)的属性和方法放在同一个内存空间下,起到了分组的作用,
//这样不同的事物之间的属性即使属性名相同,相互也不会冲突。
//--->我们把这种分组编写代码的模式叫做“单例模式”
//--->在单例模式中我们把person1或者person2也叫做命名空间。 var person1={
name:"lizebo",
age:23
};
var person2={
name:"liutinghhh",
age:22,
};
console.log("=========");
console.log(person1.name);
console.log(person2.name); //单例模式是一种项目开发中经常使用的模式,因为项目中我们可以使用单例模式进行“模块开发”
//“模块开发:”相对一个来说比较大的项目,需要多人写作的开发,我们一般下会根据当前项目的需求划分成几个功能模块,每个人负责一部分,同时开发,
//最后把代码合在一起。
</script>
</body>
</html>

2.工厂模式

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>工场模式</title>
</head>
<body> <script type="text/javascript">
var jsPerson1={
name:"walihong",
age:48,
writeJs:function () {
console.log("my name is"+this.name+",i can write javascript");
}
};
jsPerson1.writeJs();
console.log("========工厂设计模式======")
//单例设计模式是手工作业模式,虽然解决了分组的作用,但是不能实现批量生产,属于手工作业模式-->这就出现了工厂模式:顾名思义,就是批量生产。
//工厂模式就是把实现同一件事情的代码放到一个函数中,以后如果在想实现这个这个功能,不需要从新的编写这些代码来了,只需要执行当前的函数即可。
//工厂模式有一个专业的名词,“函数的封装”。--->低耦合,高内聚,减少页面中的冗余代码,提高代码的重复利用率。
function createJsPerson(name,age) {
var obj={};
obj.name=name;
obj.age=age;
obj.writeJs=function () {
console.log("my name is"+this.name+",i can write javascript");
}
return obj;
}
var personDemo1=createJsPerson("lizbeo",234);
personDemo1.writeJs();
//这样上面的方法就可以批量生产!
//js是一门轻量级的脚本“编程语言”(HTML+CSS不属于编程语言,属于标记语言)
//继承:子类继承父类中的属性和方法
//多态:当前的函数的多种形态
//在后台语言中:多态包含重载和重写 //JS中不存在重载,方法名一样的话,后面的会把前面的覆盖掉,最后只保留一个。
//为什么js面向对象但是有没有重载呢?
//1.高阶层次,在js中,存在预解释机制(js中特有的机制),它只会申明函数一次,如果遇到了
//与函数名字相同,那么它不会再次申明和定义,只会重新赋值。
//2.在函数的层次,在js函数中,所有的函数的参数都用一个类似数组的arguments接收,这个argument接收一切参数,
//即使你传入的参数比定义时候的参数多,那么它也就收并且值为undefined,而不会报错,这也间接证明了没有重载。 //js中有重写:子类重写父类的方法......未完待续!!! </script>
</body>
</html>

3.构造函数模式基础

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>构造函数模式基础</title>
</head>
<body>
<script type="text/javascript">
//构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例。
//========工厂模式例========
function creatFactor(name,age){
var obj={};
obj.name=name;
obj.age=age;
obj.methodFactoryMethod=function () {
console.log("my name is "+this.name+",my age is "+this.age+",在学JavaScript")
}
return obj;
//如果把var obj={} 和return obj去调用,并且把obj换成this,那么就变成了类;那么我们执行的时候,如果
// 使用var demo=createFactor("李泽",23);这是普通方法执行,由于没有返回值;所以
// 结果是undefined。那么this这里指的又是什么呢?由于没有人调用,这个this就是指的是
// window这个对象。。 // 而在使用new 之后,结果就返回了一个对象;为什么,简单说浏览器执行到这儿的时候,
// 一看到new这个关键字,他会自动创建一个对象并且返回,这是我们看不到的,所以我们可以
// 使用var demo来进行接收。
}
var demo=creatFactor("lizbeo",23);
demo.methodFactoryMethod(); //构造函数模式和工厂模式的区别?
//1.执行的时候
//普通函数执行-->creatFactor();
//构造函数模式:-->new creatFactor();
//通过new执行,我们的creatFactor就是一个类了。参照js内置类的命名方式,类的第一个首字母大写。
//而函数执行的返回值p1就是creatFactor这个类的一个实例
//2.函数代码执行的时候
//相同点:都是形成一个私有作用域,然后经历形式参数赋值-->预解释--->代码从上到下执行(类和普通函数一样,它有普通函数的一面)。
//不同点:在代码执行之前,不用手动创建对象了,浏览器会默认创建对象数据类型的值。
// (这个对象其实就是当前类的一个实例)
// 接下来代码从上到下执行,以当前的实例执行的主体(this代表的是当前的实例),
// 然后分别把属性名和属性值赋值给当前的实例。
// 最后浏览器会默认的把创建的实例返回。
console.log("=============")
//不需要在手动创建返回的对象,浏览器会将默认的对象返回,我们只需要定义一个var进行接收。
var p1=new creatFactor("liuhuan",23);
p1.methodFactoryMethod(); console.log("========数组实例:=========")
//比如创建一个数组:
// 字面量方式
var ary=[];
// 实例创建方式-->构造函数执行模式的方式。
var ary1=new Array();
//不管哪一种方式,ary都是Array这个类的一种实例 //1.*js中所有的类都是函数数据类型的,它通过new 执行变成了一个类,但是他本身也是一个普通的函数。---优点跟Java不一样,js直接把类归在了函数数据类型中。
//js中所有的实例都是对象数据类型的, //2.*****this的第4种用法*******在构造函数模式中,类中(函数体中)出现的this.xxx=xxx中的this是当前类的一个实例。 var p2=new creatFactor("WangXi",48);
//这里的p2是createFactor类的另外一个实例
console.log("================");
p2.methodFactoryMethod();
//3.p1和p2都是creatFactor这个类的实例,所以都拥有writeJS这个方法,但是不同实例之间的方法是不一样的。
//在类中给实例增加的属性(this.xxx=xxx)属于当前实例的私有属性,实例与实例之间是单独的个体,所以私有属性不是同一个,是不相等的。
console.log(p1.methodFactoryMethod===p2.methodFactoryMethod);//flase
</script>
</body>
</html>

4.构造函数模式扩展

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>构造函数扩展</title>
</head>
<body> <script type="text/javascript">
function Fn() {
this.x=100;
this.getX=function () {
console.log(this.x);
}
}
var f1=new Fn;
//1.在构造函数模式种,new Fn()执行,如果Fn种不传递参数,()可以省略。
//2.this的问题:在类种出现的this.xxx=xxx中的this都是当前类的实例。而某一属性值(方法),方法中的this需要看方法执行的时候,前面是不是有"."
//才能知道this所指。
f1.getX();//--->方法中的this是f1-->100
var ss2=f1.getX;
ss2();//方法中的this是window-->undefined console.log("=========例子2:==========");
function Fn1(){
var num=10;
this.x=100;
this.getx=function () {
console.log(this.x);
}
}
var f1=new Fn1;
console.log(f1.num);//undefined
console.log("=========例子3======="); function Fn3() {
var num=109;
this.x=100;
this.getX=function () {
console.log(this.x);
}
return 100;
}
var f3=new Fn3;
console.log(f3);
//4.在构造函数模式中浏览器会把我们的实例返回(返回的是一个对象数据类型的值);如果我们自己手动写了return返回;
//返回的是一个基本的数据类型的值,当前实例是不变的,列如:return 100;
//我们的f3还是当前Fn3类的实例
//返回的是一个引用数据类型的值,当前的实例会被自己返回的值给替换掉,列如:
//return(name:"哈哈")我们的f3就不再是Fn3的实例了,而是对象{name:"哈哈"}; //5.检测某一个实例是否属于一个类-->instanceof
console.log(f3 instanceof Fn3);//--->true;
console.log(f3 instanceof Array);//---->false;
console.log(f3 instanceof Object);//---->true;因为所有的实例都是Object类型的
//而每一个对象数据类型都是Object这个内置类的一个实例,为啥这样?未完待续!!!!
console.log("========================")
//对于检测数据类型来说,typeof有自己的局限性,不能区分Object下的对象,数组,正则。
var a=[];
console.log(a instanceof Array);//-->true
//6.检测共有属性。
var f4=new Fn3;
var f5=new Fn3;
//in:检测某一个属性是否属于这个对象 attr in object,不管是私有的还是公有的属性,只要存在,用in 来检测都是true
console.log("getX" in f5);//-->true 是它的一个属性。
//hasOwnProperty:用来检测某一个属性是否为对象的“私有属性”,这个方法只能检测私有的属性
console.log(f5.hasOwnProperty("getX"));//--->true "getX"是f5的私有属性。 //思考:检测一个属性是否是对象的“公有属性” hasGongYou方法
function hasGongYou方法 (obj,attr) {
if(attr in obj){
if(jianCe.hasOwnProperty(attr)){
return true;
}
}
else {
return false;
}
}
var jianCe={name:"lizbeo"};
var zhenJia=hasGongYou方法(jianCe,"name")
console.log("====================")
console.log(zhenJia)
//简写
function hasPubProperty(object1,attr) {
return (attr in object1) && !object1.hasOwnProperty(attr);
}
var jianCe1={name:"lizbeo"};
var zhenJia1=hasGongYou方法(jianCe1,"name")
console.log("===========")
console.log(hasPubProperty(jianCe1,"name")) ; //7.isPrototypeOf
</script>
</body>
</html>

5原型链模式基础

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>15原型链模式基础</title>
</head>
<body> <script type="text/javascript">
// 1.类例子回顾--构造函数模式 console.log("===============原型链的引出======================")
function createDemo(name,age) {
this.name=name;
this.age=age;
this.writeJs=function () {
console.log("my name is"+this.name+",i can write Js");
};
}
var p1=new createDemo("liuhze",234);
var p2=new createDemo("liuhuan",25);
console.log(p1.writeJs===p2.writeJs);//false;
//构造函数拥有了类和实例的概念,并且类和实例之间是相互独立开的-->实例识别。
// 2.可不可以让私有的writeJs方法,成为共有的呢?也就是说,我们实例化2个对象p1和p2他们有公有的方法
function createDemo2(name,age) {
this.name=name;
this.age=age;
createDemo2.prototype.writeJs=function () {
console.log("my name is"+this.name+", i can write JS ");
};
}
var p3=new createDemo2("李强",23);
var p4=new createDemo2("刘华",26);
console.log(p3.writeJs===p4.writeJs);//这样结果就是true了,这2个实例调用了公有的方法。
//基于构造函数模式的原型模式解决了 方法或者属性公有的问题-->把实例之间相同的属性和方法提取成公有的属性和方法---》
//想让谁公有就把它放在createJsPerson.prototype上即可。 console.log("=====================原型链==============================="); //1.每一个函数数据类型(普通函数,类)都有一个天生的自带属性:prototype(原型),并且这个属性是一个对象数据类型的值
//2.并且在prototype上浏览器天生给它加了一个属性constructor(构造函数),属性值是它当前函数(类)本身。
//3.每一个对象数据类型(普通的对象,实例,prototype)也天生自带一个属性:__proto___,
//这个属性值是当前实例所属类的原型(prototype)。 function Fn() {
this.x=100;
Fn.prototype.getX=function () {
console.log(this.x);
}
}
var f1=new Fn();
var f2=new Fn();
console.log(f1.getX===f2.getX);//true
console.log(Fn.prototype.constructor);//结果是函数Fn的代码字符串!!!
//原理见图原型链1.png
console.log(Fn.prototype.constructor===Fn);//true
// 2 .Object是所有JS中所有对象数据类型的父类(最顶层的类)
//1).f1 instanceof Object-->true因为f1通过__proto__可以想上级查找
//不管有多少级,最后总能找到Object.
//2).在Object.prototype上没有__proto__这个属性, // 3.原型链模式
//f1.hasOwnProperty("x");hasOwnProperty是f1的一个属性
//但是我们发现在f1的私有属性上并没有这个方法,那如何处理呢?
//通过 对象名.属性名获取属性值的时候,首先在对象的私有属性上进行查找,如果私有的属性存在这个属性则
//获取的是私有属性值;
//如果私有属性没有,则通过__proto__找到所属类的原型(类的原型上定义的属性和方法都是当前实例的公有的属性和方法),
//原型上存在的话,获取公有的属性值;
//如果原型上也没有,则继续通过原型上的__proto___继续向上查找。一直找到Object.prototype为止。
//这种查找机制就是我们的“原型链模式” // 练习题
console.log("===========原型链的练习题==========");
var tf1=f1.getX===f2.getX;//---->true
console.log(tf1);
console.log(f1.__proto__.getX===f2.getX);//--->true
console.log(f1.getX===Fn.prototype.getX);//--->true; console.log(f1.hasOwnProperty===f1.__proto__.__proto__.hasOwnProperty);//true;
//在IE浏览器中,我们原型模式也是同样的原理,但是IE浏览器怕你通过__proto__把公有的修改,禁止使用__proto__.
//IE浏览器会有保护机制,所以不让你通过__proto__一直修改属性,他会提示这个属性不存在。
</script>
</body>
</html>

6.原型链模式扩展-this和原型扩展

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>课时16:原型链模式扩展-this和原型扩展</title>
</head>
<body> <script type="text/javascript">
//在原型模式中,常用的有2中情况:
//在类中this.xxx=xxx;this--->当前累的实例
//在某一个方法中this--->看执行的时候,”."前面是谁,就是谁。
//1)需要先确定this的指向(this是谁)
//2)吧this替换成对应的代码
//3)按照原型链查找机制,一步步查找数值。
function Fn() {
this.x=100;
this.y=100;
this.getY=function () {
console.log(this.y);
};
}
Fn.prototype={
constructor:Fn,
y:300,
getX:function () {
console.log(this.x);
},
getY:function () {
console.log(this.y);
}
} var f=new Fn;
f.getX();//执行的是公有属性中的getX()方法,先去找私有的,没有去找公有的。100
//-->执行步骤:console.log(f.x)-->100
//f.__proto__.getx();//结果是undefined,有意思吧。
//this是f.__proto__--->f.__proto__.x-->没有x的值,再去找Object的值,没有所以undefined。
// 练习题
Fn.prototype.getX();//---->undefined
f.getY();//---->200;
// f.__proto__.getY();f//---->300;
console.log("========数组实现内置方法去重======")
Array.prototype.myUnique=function () {
//this--->
console.log("这是原型链中公有的方法,使用ary.myUnique执行的是公有方法!")
var obj={};
for(var i=0;i<this.length;i++){
var cur=this[i];
if(obj[cur]==cur){
this[i]==this[this.length-1];
this.length--;
i--;
continue;
}
obj[cur]=cur;
}
obj=null;
};
var ary=[];
var ary1=[12,34,34,34,34,34,56,66,66,66,777];
ary.myUnique();
Array.prototype.myUnique();
ary1.myUnique();
console.log(ary1); //数组排序之链式写法
console.log("===========数组排序之链式写法=========")
//原理:
//aryDemo为什么可以使用sort方法?因为sort是Array.prototype上公有的方法,而数组是
//aryDemo是Array这个类的一个实例,所以可以使用sort方法--->所以只有数组才能使用Arra
//y原型上定义的属性和方法。
//sort执行完成的放回置是一个排序后的“数组”,(其实就是为了实现执行后返回的还是一个数组的实例)
//reverse执行完成的返回值是一个数组,可以继续执行pop
//pop执行完成的返回值是被删除的那个元素,不是一个数组了。也就是说pop后面是不能在继续”.“了。
//要想弄清楚为什么这样写必须搞清楚对象的原型链
//
//一句话:要想实现链式写法必须返回的是一个类的实例。
var aryDemo=[12,34,23,4,3,343,45,34,34,34,656];
aryDemo.sort(function (a,b) {
return a-b;
}).reverse().pop();
console.log(aryDemo); </script>
</body>
</html>

7.原型链模式扩展-this和原型扩展-练习题

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>课时16:原型链模式扩展-this和原型扩展-练习题</title>
<!--在数组的原型上有一个方法叫做slice,要求:自己实现一个myslice方法。
Array.prototype.mySlice=function(){
<js code >
}
考虑的情况:
slice(n,m);
slice(n);
slice();
n和m是负数,什么情况?
n<m是什么情况
n和m的值超过数组的长度是什么情况
n和m不是有效数字是什么情况
.
..
... 不能使用数组内置的方法:不能使用数据内置的方法,比如添加不能使用push,
而是用ary[ary]; 2.(面试题)实现一个需求:
(5).plus(10).reduce(2) 5+10-2
Number.prototype.plus=function(num){};
Number.prototype.reduce=function(num){}; -->
</head>
<body>
<script type="text/javascript"> </script>
</body>
</html>

8.原型链模式扩展-批量设置公有属性

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>课时17:原型链模式扩展-批量设置公有属性</title>
</head>
<body>
<script type="text/javascript">
console.log("批量设置原型上的公有属性!"); //jQuery就是使用这种方式进行构架的
function Fn() {
this.x=10;
}
//1.起别名
var pro=Fn.prototype;//把原来类型指向的地址赋值给我们的pro,现在他们
//操作的是同一个内存空间
pro.getX=function () { };
//2.重构原型对象的方式-->自己重新开辟一个堆内存,
function Fn1() {
this.x=100;
}
Fn1.prototype={
constructor:Fn1,//必须手动指定constructor否则就是Object了。这样做的目的就是为了保持一直。
a:function () {
console.log("我是重构的!");
},
b:function () { },
};
var f=new Fn1;
//能执行a.
//1)只有浏览器天生给Fn.prototype开辟的堆内存里面才有constructor,而而我们自己开辟
//的这个堆内存没有这个属性,这样constructor指向不在是Fn而是Object了
//为了和原来的保持一直,需要手动的增加constructor的指向
//手动增加一个constructor:Fn1
f.a();
console.log(f.constructor);
f.b(); //2.用这种方式给内置类增加公有的属性
//给内置类Array增加数组去重的方法
Array.prototype.unique=function () {
//js code
}; Array.prototype={
constructor:Array,
unique:function () { },
};
console.log("=====强行清空Array内置方法===========")
console.dir(Array.prototype);
//我们使用方式会把之前已经存在原型上的属性和方法替换掉,所以我们中这种方法
//修改内之类的话,浏览器是给屏蔽的。
//但是我们可以一个一个的修改浏览器的内置方法。如果方法名和原来的内置的重复了,
//会把人家内置的修改掉---->以后我们在内置内的原型上增加方法,命名都需要加上特殊的前缀。
console.log("===========另外一个例子===============");
var ary=[1,2,3,4,5,6,7];
ary.sort();
console.log(ary); Array.prototype.sort=function () {
// console.log(this)//this-->aryDemo 我们当前操作的对象,
console.log("ok!");
}
// 修改数组中的内置方法,sort使他成为自己的内置方法。
var aryDemo=[1,2,2,1,2,2,3,4,5,6,7];
aryDemo.sort();
console.log(aryDemo);
</script>
</body>
</html>

9.深入扩展原型链模式常用的六种继承方式

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>18.深入扩展原型链模式常用的六种继承方式</title>
</head>
<body> <script type="text/javascript">
//--->div ,a,document,window, function Fn() {
this.x=100;//这里的this指的是Fn的一个实例
//->在类的函数体中写的this.xxx=xxx都是当前类的实例
this.getX=function () {
console.log(this.x);
}
}
Fn.prototype.getX=function () {
console.log(this.x);
};
Fn.prototype.setX=function (n) {
this.x=n;
};
//在类的原型上写的都是给当前类的实例或者当前类
//见图片原型链图片.PNG
var f1=new Fn;
console.log(f1.hasOwnProperty("x"));
//1.所有的函数数据类型都天生自带一个属性:prototype,它存储的值是一个对象数据类型的值,浏览器默认为其开辟一个对
//一个堆内存
//2.在浏览器默认给prototype默认开辟的这个堆内存上都有一个默认的属性:
//constructor,指向当前类本身
//3.每一个对象数据类型(普通函数,数组,正则,实例,prototype)都天生自带一个属性(__proto__):__prototype__,指向当前实例所属类的原型。
var f1=new Fn;
var f2=new Fn; //1.看方法执行的时候,”.“前面是谁,this就是谁。
//2.吧函数中this替换成分析的结果
//3.按照原型链的查找模式找到对应的值即可
f1.getX();//100;f1.getX();,console.log(f1.x);
// 练习
f2.getX();//100;
f2.__proto__.getX();//this-->f2.__prototype__,结果是undefined Fn.prototype.setX(300);//X设置成300;
f2.getX();//100;
f2.__proto__.getX();//300 </script>
</body>
</html>

JavaScript提高篇之面向对象之单利模式工厂模型构造函数原型链模式

10.一道题(原型链)

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
function Fn(num) {
this.x=this.y=num;
}
Fn.prototype={
x:20,
sum:function () {
console.log(this.x+this.y);
}
};
var f=new Fn(10);
console.log(f.sum==Fn.prototype.sum);//true;
f.sum();////f.x=10 f.y=10 结果为20
Fn.prototype.sum();//this.x=20; 结果是: NaN;
console.log(f.constructor);//Object //这道题可以的。
</script> </body>
</html>

11.原型链复习

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原型链综合复习参考2</title>
</head>
<body>
<script type="text/javascript">
function Fn() {
this.x=100;
}
Fn.prototype={
//注意构建 constructtor.
//浏览器不会开constructtor,但是我可以自己加啊。
constructor:Fn,
a:function () { },
b:function () { }, };
var f=new Fn;
//这种方式如果之前原型上存在一些方法,我们现在新创建的对象会把之前写的那些覆盖掉。
//但是所有内置类的原型都有保护;
//比如:
Array.prototype={};
//所以浏览器禁止创建一个新对象来扩展原型上的方法,
//自己创建的对象不会天生自带constructor,所以导致了我们的f.constructor的结果
//是Object而不是我们认为的Fn了。 </script>
</body>
</html>

12.在内之类的原型上扩展方法

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>在内之类的原型上扩展方法</title>
</head>
<body> <script type="text/javascript">
var ary=[11,22,33,44];
ary.pop();//this-->ary
ary.__proto__.pop();//this--->ary.__proto__-->Array.prototype
//这种方式不可以删除。 //基于内置类的原型扩展方法,我们需要注意的事项:我们自己编写的方法名最好加上特殊的前缀,防止把内置方法覆盖掉
Array.prototype.myPaixu=function myPaixu () {
//this-->ary;
var obj={};
for (var i =0;i<this.length;i++){
var cur=this[i];
if(obj[cur]==cur){
this[i]=this[this.length-1];
this.length--;
i--;
continue; }
obj[cur]=cur;
}
obj=null;
//实现链式写法。
return this;
};
var ary1=[1,2,2,3,3,5,66,66,66];
ary1.myPaixu().sort(function (a,b) {
return a-b;
});
console.log(ary1);
</script>
</body>
</html>

13.深入扩展原型链模式常用的六种继承方式(1)

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>19深入扩展原型链模式常用的六种继承方式</title>
</head>
<body>
<script type="text/javascript"> var obj={};
var obj=new Object();
//这2中方式没有区别,一个是字面量,一个是通过构造函数方式。 //扩展Object属性
Object.prototype.aaa=function AAA() {
console.log("我是自定义的公有属性!")
}; var obj2={name:"lizbeo",age:23};
for (var shuXing in obj2){
//---->for in 循环在遍历的时候可以把自己私有的和在它
//所属类的原型上扩展的属性和方法都可以遍历到
//但是一般情况下,我们遍历一个对象只需要遍历私有的即可,
//我们可以使用以下的判断
if(obj2.propertyIsEnumerable(shuXing)){}
console.log(shuXing);
// if(obj2.hasOwnProperty(shuXing)){
// console.log(shuXing)
// }
}
</script>
</body>
</html>

14.深入扩展原型链模式常用的六种继承方式(2)

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>19深入扩展原型链模式常用的六种继承方式2</title>
</head>
<body> <script type="text/javascript">
// 1. 原生继承!!!!!!!!!
//--->#div.__pro__-->HTMLDivElement.prototype-->HTMLElement.prototype
//-->Element.prototype-->Node.prototype--->EventTarget.prototype--->O
//bject.prototype;
function myObject() {
this.getInformation=function () {
console.log("我是myObject的私有属性!");
} }
myObject.prototype=new Object;
myObject.prototype.aaaaaa=function () {
console.log("我是继承原生继承!");
}; function myTargetElement () { }
myTargetElement.prototype=new myObject; var A=new myTargetElement();
A.aaaaaa();
A.getInformation();
//这就是原生继承。
//====》原生继承是我们JS中最常用的继承方式,
//-----》1)子类B想要继承父类A中的属性和方法(私有+公有),只需要让B的prototype=new A的一个实例;即可
//注意以下,所有方法,包括私有方法很关键。
//2)原型继承有个特点:他是把父类中私有的+公有的都继承到了子类的原型上(子类公有) </script>
</body>
</html>

15.深入扩展原型链模式常用的六种继承方式(3)

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>19深入扩展原型链模式常用的六种继承方式3</title>
</head>
<body> <div id="div1"></div>
<script type="text/javascript">
var doc=document.getElementById("div1");
// 原型链的核心:见图 原型链的核心思想.PNG
//原生继承并不是把父类中的属性和方法克隆一份一摸一样的给B,而是让B和A之间增加了原型链的连接,以后B的实例想要从A中
//获得getX的方法,需要一级一级的去查找。
//但是有一个弊端:
//见图 原型链的核心思想2.PNG //--->核心:原型继承并不是把父类中的属性和方法克隆一个一摸一样的给B,而是让B和A之间增加了原型链的连接,以后B的实例想要从
//A中的getX方法,需要一级级向上查找来使用。 </script>
</body>
</html>

16.深入扩展原型链模式常用的六种继承方式(4)

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>19深入扩展原型链模式常用的六种继承方式之其他继承</title>
</head>
<body> <script type="text/javascript">
// function A() {
// this.x=100;
// }
// A.prototype.getX=function () {
// console.log(this.x);
// };
// function B() {
//
// A.call(this);
// }
// var n=new B;
// console.log(n.x);
// //call继承:就是把父类私有的属性和方法 克隆一根一摸一样的作为子类私有的属性
// 还有一些继承 :1.冒充对象继承:把父类私有的+公有的克隆一份一摸一样的给子类。
</script>
</body>
</html>

--lzb