函数及原型链

##函数

  • 私有变量外部无法访问:
function Obj1() {
     var a = 0; //私有变量
     var fn = function() { //私有函数
     }
 }
  • 静态变量新调用的函数不传递此变量:
 function Obj2() {
 }
 Obj2.a = 0; //静态变量
 Obj2.fn = function() { //静态函数
 }
var o = new Obj2();
console.log(o.a);//undefined
  • 每个创建的函数都会初始化Obj3.a变量,但值不传递:
function Obj3() {
    this.a = []; //实例变量
    this.fn = function() { //实例方法
    }
}
var o1 = new Obj3();
console.log(o1.a); //[]
  • prototype值共享,统一指向同一个指针,每个new函数都能使用和修改:
function Person(name) {
    this.name = name;
}
Person.prototype.share = [];
Person.prototype.printName = function() {
    alert(this.name);
}
var person1 = new Person('Byron');
var person2 = new Person('Frank');
person1.share.push(1);
person2.share.push(2);
console.log(person2.share); //[1,2]
  • 构造函数:
 function Person(name) {
   this.name = name;
 }
 // 定义Person的原型,原型中的属性可以被自定义对象引用
 Person.prototype = {
   getName: function() {
     return this.name;
   }
 }
 var hao= new Person("haorooms");
 console.log(hao.getName());  // "haorooms
另一种模式:
function person(firstname,lastname,age,eyecolor)
{
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;
 
this.changeName=function(name)
{
this.lastname=name;
}
}
myMother=new person("Steve","Jobs",56,"green");
myMother.changeName("Ballmer");

  • 跨函数调用c1.showNam.call(c2):
    call 的意思是把 c1 的方法放到c2上执行,原来c2是没有showNam() 方法,现在是把c1 的showNam()方法放到 c2 上来执行,所以this.name 应该是 class2,执行的结果就是 :alert(“class2”);:
function Class1() {
    this.name = "class1";
    this.showNam = function() {
        alert(this.name);
    }
}
function Class2() {
    this.name = "class2";
}
var c1 = new Class1();
var c2 = new Class2();
c1.showNam.call(c2);
  • 类式继承:
    类式继承是在子类型构造函数的内部调用超类型的构造函数。
    严格的类式继承并不是很常见,一般都是组合着用:
function Parent(age){
    this.name = ['mike','jack','smith'];
    this.age = age;
}

function Child(age){
    Parent.call(this,age);
}
var test = new Child(21);
alert(test.age);//21
alert(test.name);//mike,jack,smith
test.name.push('bill');
alert(test.name);//mike,jack,smith,bill
  • 原型链继承:
    为了让子类继承父类的属性(也包括方法),首先需要定义一个构造函数。然后,将父类的新实例赋值给构造函数的原型。代码如下:
 function Parent(){
  this.name = 'mike';
 }

 function Child(){
     this.age = 12;
 }
 Child.prototype = new Parent();//Child继承Parent,通过原型,形成链条
 var test = new Child();
 alert(test.age);
 alert(test.name);//得到被继承的属性
 //继续原型链继承
 function Brother(){   //brother构造
     this.weight = 60;
 }
 Brother.prototype = new Child();//继续原型链继承
 var brother = new Brother();
 alert(brother.name);//继承了Parent和Child,弹出mike
 alert(brother.age);//弹出12
  • 组合继承:
    为了让子类继承父类的属性(也包括方法),首先需要定义一个构造函数。然后,将父类的新实例赋值给构造函数的原型。组合式继承是js最常用的继承模式,但组合继承的超类型在使用过程中会被调用两次;一次是创建子类型的时候,另一次是在子类型构造函数的内部,代码如下:
function person(name,age){
    this.name =name;
    this.age = age;
}
//唱歌
person.prototype.sing = function () {
    return this.name  + ' are singing';
};
//跳舞
person.prototype.dance = function () {
    return this.name  + ' are dancing';
};
person.prototype.number = 0;

function child(father,mother,name,age){
    this.father =father;
    this.mother = mother;
    person.call(this,name,age);//person(name,age)类式继承
}
child.prototype=new person();//原型链继承,继承父类属性
child.prototype.cry=function () {
    return this.name  + ' are crying';
};
var mother=new person('小红',20);
var father=new person('小红老公',30);
var child1=new child(father.name,mother.name,'child','0');
alert(mother.number);
alert(child1.number);
示例2:
function Parent(age){
  this.name = ['mike','jack','smith'];
    this.age = age;
}
Parent.prototype.run = function () {
    return this.name  + ' are both' + this.age;
};
function Child(age){
    Parent.call(this,age);//对象冒充,给超类型传参
}
Child.prototype = new Parent();//原型链继承
var test = new Child(21);//写new Parent(21)也行
alert(test.run());//mike,jack,smith are both21
  • 原型式继承:
    这种继承借助原型并基于已有的对象创建新对象,同时还不用创建自定义类型的方式称为原型式继承
function obj(o){
     function F(){}
     F.prototype = o;
     return new F();
 }
var box = {
    name : 'trigkit4',
    arr : ['brother','sister','baba']
};
var b1 = obj(box);
alert(b1.name);//trigkit4
b1.name = 'mike';
alert(b1.name);//mike

alert(b1.arr);//brother,sister,baba
b1.arr.push('parents');
alert(b1.arr);//brother,sister,baba,parents

var b2 = obj(box);
alert(b2.name);//trigkit4
alert(b2.arr);//brother,sister,baba,parents
  • 寄生式继承:
    这种继承方式是把原型式+工厂模式结合起来,目的是为了封装创建的过程。
function obj(o){
     function F(){}
     F.prototype = o;
     return new F();
 }
function create(o){
	var f= obj(o);
    f.run = function () {
        return this.arr;//同样,会共享引用
    };
    return f;
}
  • 寄生组合式继承:
 function inheritPrototype(subType, superType){
    var protoType = Object.create(superType.prototype); //创建对象
    protoType.constructor = subType;     //增强对象
    subType.prototype = protoType;      //指定对象
   }
   function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
   }
   SuperType.prototype.sayName = function(){
    alert(this.name);
   }
    
   function SubType(name, age){
    SuperType.call(this, name);  //第二次调用SuperType()
     
    this.age = age;
   }
   inheritPrototype(SubType, SuperType)
   SubType.prototype.sayAge = function(){
    alert(this.age);
   }
    
   var instance = new SubType("Bob", 18);
   instance.sayName();
   instance.sayAge();
改进版:
 function person(name,age){
    this.name =name;
     this.age = age;
 }
 //唱歌
 person.prototype.sing = function () {
     alert(this.name  + ' are singing');
     return this;
 };
 //跳舞
 person.prototype.dance = function () {
     return this.name  + ' are dancing';
 };

 function child(father,mother,name,age){
     this.father =father;
     this.mother = mother;
     person.call(this,name,age);//person(name,age)类式继承
 }
 child.prototype.cry=function () {
     return this.name  + ' are crying';
 };
 //对象合并
 Object.prototype.assign=function(o,n){
    for (var p in n){
         if(n.hasOwnProperty(p) && (!o.hasOwnProperty(p) ))
             o[p]=n[p];
     }
     return o;
 };
 function inheritPrototype(person,child){
   var protoType=Object.assign(child.prototype,person.prototype);
   /*var protoType = Object.create(person.prototype);*/ //创建对象,child的prototype需要后赋值
   protoType.constructor = child; //增强对象
   child.prototype = protoType;//指定对象
 }
 inheritPrototype(person,child);//先把父级的复制过来
 var mother=new person('小红',20);
 var father=new person('小红老公',30);
 var child1=new child(mother.name,father.name,'child','2');
 
 alert(child1.name);
 alert(child1.age);
 alert(child1.father);
 alert(child1.sing().cry());
 另一模式:
 使用apply来链接构造器
你可以使用apply来给一个对象链接构造器,类似于Java. 在接下来的例子中我们会创建一个叫做construct的全局的Function函数,来使你能够在构造器中使用一个类数组对象而非参数列表。
 Function.prototype.construct = function (aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};
 Function.prototype.construct = function(aArgs) {
  var fConstructor = this, fNewConstr = function() { 
    fConstructor.apply(this, aArgs); 
  };
  fNewConstr.prototype = fConstructor.prototype;
  return new fNewConstr();
};

##闭包

  • 模块化:
var serial_maker = function() {
	var prefix = '';
	var seq = 0;
	return {
		set_prefix: function(p) {
			prefix = new String(p)
		},
		set_seq: function(s) {
			seq = s;
		},
		gensym: function() {
			var result = prefix + seq;
			seq += 1;
			return result;
		}
	}
}
var seqer = serial_maker();
seqer, set_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym(); //unique是"Q1000"
  • 释放内存:
    解决prefix和seq会一直存在内存中直到页面关闭,变量会在函数执行完毕后就进行释放
(function() {
	var serial_maker = function() {
		var prefix = '';
		var seq = 0;
		return {
			set_prefix: function(p) {
				prefix = new String(p)
			},
			set_seq: function(s) {
				seq = s;
			},
			gensym: function() {
				var result = prefix + seq;
				seq += 1;
				return result;
			}
		}
	}
})();
  • 结合继承实现闭包:
 Function.prototype.curry = function() {
 	var slice = Array.prototype.slice,
 		args = slice.apply(arguments), //因为arguments不是真正的数组,只是类似数组的一个对象,所以这里要将arguments转换为数组
 		that = this;
 	debugger;
 	return function() {
 		return that.apply(null, args.concat(slice.apply(arguments)))
 	}
 };
 var add = function() {
 	var total = 0;
 	for (var i = 0; i < arguments.length; i++) {
 		total += arguments[i];
 	}
 	return total;
 };
 var add1 = add.curry(1);
 document.writeln(add1(6)); //7
  • 指定条件执行:
var judage = function(){
    if($("#a").text == true){
        //做你想做的的事
    }
    else{
        //500毫秒轮询一次
        setTimeout(judage, 500)
    }
}
  • Angular函数:
方式1:$scope.totalPrice=function(){
    	return 1000;
}
方式2:function totalPrice ($scope) {
       return 1000;
}
$scope.getCountry = function (city) {
   switch (city) {
        case "London":
            return "UK";
        case "New York":
            return "USA";
    }
}

##计时器

var int = setInterval(function() {
            }, 80);
clearInterval(int);停止计时
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GY程序源

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值