继承发展史
1.传统形式---->原型链()过多的继承了没用的属性
2.借用构造函数(call/apply)不能继承借用构造函数的原型,每次构造函数都要多走一个函数
3.共享原型不能随便改动自己的原型
4.圣杯模式
3.共享原型
例1
Father.prototype.lastName="Deng";
function Father(){
}
function Son() {
}
Son.prototype=Father.prototype
var son = new Son();
var father = new Father();
//son.lastName=father.lastName
例2
Father.prototype.lastName = "Deng";
function Father() {
}
function Son() {
}
function inherit(Target,Origin) {
Target.prototype = Origin.prototype;
}
inherit(Son,Father);
Son.prototype.sex="male";
var son = new Son();
var father = new Father();
inherit(Son,Father);
//继承了再改不好使son.latName=undefined 想给son加一个独有的东西,但会影响到father,如图,所以用圣杯模式
4.圣杯模式
extend/inherit继承
例3
//方法一
function inherit(Target,Origin) {
function F() {};
F.prototype = Origin.prototype;//
Target.prototype = new F();
// Target.prototype.constructor = Target;//把son的constructor变成自己的constructor
// Target.prototype.uber = Origin.prototype//对象的超类,看到真正继承自谁father.prototype
}
Father.prototype.lastName="Deng";
function Father() {
}
function Son() {
}
inherit(Son,Father);
var son = new Son();
var father = new Father();
// 方法二
function inherit(Target,Origin){
// var inherit = (function(){
// var F = function(){};
// return function(Target,Origin) {
// F.prototype = Origin.prototype;
// Target.prototype=new F();
// Target.prototype.constructor = Target;
// Target.prototype.uber = Origin.prototype;
// }
// }());
}
Father.prototype.lastName="Deng";
function Father() {
}
function Son() {
}
inherit(Son,Father);
var son = new Son();
var father = new Father();
命名空间
管理变量,防止污染全局,适用于模块化开发
一开始使用的方法命名空间例子
var org = {
deparment1:{
jicheng:{
name:"abc",
age:123,
},
xuming:{
}
}
},
department2{
zhangsan:{
},
lisi:{
}
}
org.department1.jicheng.name
var jicheng = org.department1.jicheng
现在用webpack
新方法用闭包。模块化开发,防止污染全局变量
例一
var init = 'bcd';//init入口,初始化
var init = (function(){
var name="abc";
function callName(){
console.log(name);
}
return function() {
callName();//留出来一个接口,留出来一个function,里面执行函数作为终端,传给init,功能实现了,
}
}())
// init();//abc//形成了一个闭包,变量私有化,不会污染全局变量,把特定的功能写进去
var initDeng=(function() {
var name=123;
function callName(){
console.log(name);
}
return function(){
callName();
}
}())
调用哪个出来哪个
实现方法的连续调用:return this
例子2
var deng={
smoke : function(){
console.log("smoking is cool!");
return this;
},
drink : function(){
console.log("drinking is cool!");
return this;
},
perm : function(){
console.log("preming is so cool!");
return this;
}
}
deng.smoke().drink().perm().smoke().drink().perm();
属性的表示方法
例3
var deng = {
wife1:{name:"xiaoliu"},
wife2:{name:"xiaowang"},
wife3:{name:"xiaozhang"},
wife4:{name:"xiaoyang"},
sayWife:function(num){
return this['wife'+num];//字符串拼接用方括号[]
}
}
obj.name-->obj['name']
for in循环,实现对象的遍历,枚举。想要调用属性,必须写方括号[],不用加字符串",自身就是一个变量
1.hasOwnProperty 2.in 3.instance of
例4
var obj={
name:"13",
age:123,
sex:"male",
height:180,
weight:75
}
for(var prop in obj){//单独给对象设置循环
// console.log(typeof(prop)+" "+prop);//遍历所有属性名
console.log(obj[prop]);//遍历属性里面的值,把prop当作变量,代表不同的字符串
// console.log(obj.prop);//5个undefined
// console.log(obj.prop===obj['prop']);//把prop当成属性了,.是调用
}
例5 hasOwnProperty(检验是不是自己的属性) ----和in(能不能在对象上调用某个属性)(控制台"height"in obj)
var obj={
name:"13",
age:123,
sex:"male",
height:180,
weight:75,
__proto__:{
lastName:"deng",
}//也会被打印出来
}
for(var prop in obj){
if(obj.hasOwnProperty(prop)){//判断属性是不是自身的,不是自身的方法false
console.log(obj[prop]);
}
}
例6.
instanceof类似于in的操作用法,但是完全不同,A inatanceof B-->A对象是不是B构造函数构造出来的
A inatanceof B看A对象的原型链上有没有B的原型---->例子person instanceof Object(true)--->person原型链上有Object原型
function Person(){
}
var person=new Person();
区别数组对象的三种方法:constructor/instanceof/toString
例7
Object.prototype.toString.call();
Object.prototype.toString=function(){
识别this
返回相应的结果
}
obj.toString();