function Super(arg){
this.arr1 = "I'm super "+arg;
this.show = function(){
alert(this.arr1);
}
}
Super.prototype.say = function(){
alert(this.arr1);
}
function suber(arg){
Super.apply(this, arguments); //在suber的上下文中运行super
}
var sub =new suber("suber");
var sub2 = new suber("suber1");
console.log(sub.arr1); //I'm super suber
console.log(sub.show); //function (){ alert(this.arr1);}
console.log(sub.say); //undefined
console.log(sub.show === sub2.show); //false
哎呀,发现sub.say是undefined,这说明它没有被继承过来啊,下边两个对象sub,sub2的show不相等,说明两个函数指向了两个不同的对象,也就是说被复制了两份出来。
所以这个方法实现继承的话原型对象上的属性和方法没有被继承过来,Super上的属性和方法为每个new出来的对象分别复制一份。
所以单单使用这个方法来实现继承还是不妥啊,因为原型上的方法都没有被继承过来啊。于是大神们就想到了原型继承
[b]二、原型继承:[/b]
function Super(arg){
this.arr1 = "I'm super "+arg;
this.show = function(){
alert(this.arr1);
}
}
Super.prototype.say = function(){
alert(this.arr1);
}
function suber(arg){}
suber.prototype = new Super();
var sub = new suber("suber1");
var sub2 = new suber("suber2");
console.log(sub.arr1); //I'm super undefined
console.log(sub.show); //function (){ alert(this.arr1);}
console.log(sub.say); //function (){ alert(this.arr1);}
console.log(sub.show === sub2.show); //true;
console.log(sub.say === sub2.say); //true;
这次是arr1继承过来了,但是参数没有添加进来,是undefined,所以这个方法子类声明时候这个参数传进来付类继承过来的这个属性没法收到。其他的都还算正常。show和say都继承过来了。但是有一点儿需要注意,say是通过super的原型对象继承过来的,而show是新建super对象实例时实例的属性。
那么怎么实现参数传输又能把原型里边的东东继承过来呢,当然上边两种方法组合一下就好了啊,于是前辈们又发明了下面这种方法
[b]三、组合继承(借用构造函数并设置原型):[/b]
function Super(arg){
this.arr1 = "I'm super "+arg;
this.show = function(){
alert(this.arr1);
}
}
Super.prototype.say = function(){
alert(this.arr1);
}
function suber(arg){
Super.apply(this, arguments);
}
suber.prototype = new Super();
var sub = new suber("suber1");
var sub2 = new suber("suber2");
console.log(sub.arr1); //I'm super suber1
console.log(sub.show); //function (){ alert(this.arr1);}
console.log(sub.say); //function (){ alert(this.arr1);}
console.log(sub.show === sub2.show); //false;
console.log(sub.say === sub2.say); //true;
function Super(arg){
this.arr1 = "I'm super "+arg;
}
Super.prototype.show = function(){ //这个方法放到了原型对象上。
alert(this.arr1);
}
Super.prototype.say = function(){
alert(this.arr1);
}
function suber(arg){
Super.apply(this, arguments);
}
/*inherit函数的作用,使用一个新的空函数,来切断父类对象的原型对象与子类原型对象的直接联系,而是通过这个空构造的实例对象实现继承,这样可以避免更改子类原型的属性或者方法而影响了父类原型对象的属性或者方法。*/
function inherit(obj){
function F(){}
F.prototype = obj;
return new F();
}
suber.prototype = inherit(Super.prototype);
var sub = new suber("suber1");
var sub2 = new suber("suber2");
console.log(sub.arr1); //I'm super suber1
console.log(sub.show); //function (){ alert(this.arr1);}
console.log(sub.say); //function (){ alert(this.arr1);}
console.log(sub.show === sub2.show); //true;
console.log(sub.say === sub2.say); //true;
function extend(Super,suber){
suber = suber || {};
for(var i in Super){
if(Super.hasOwnProperty(i)){
suber[i] = Super[i];
}
}
return suber;
}
var parent = {
name:"dad",
num:[1,2,3],
say:function(){alert("dad");}
}
var child = {
age:5,
sex:"boy"
};
child = extend(parent, child);
//以下测试
console.log(child); /*{
age:5,
sex:"boy",
name:"dad",
num:[1,2,3],
say:function(){alert("dad");}
}*/
console.log(child.say === parent.say); //true
console.log(child.num === parent.num); //true
function extenddeep(Super, suber){
var tostr = Object.prototype.toString, astr = "[object Array]";
suber = suber || {};
for(var i in Super){
if(Super.hasOwnProperty(i)){
if(typeof Super[i] === "object"){
suber[i] = (tostr.call(Super[i]) == astr) ? [] : {};
extenddeep(Super[i],suber[i]);
}else {
suber[i] = Super[i];
}
}
}
return suber;
}
var parent = {
name:"papa",
num:[1,2,3],
say:function(){alert("I'm father of my son!");}
}
var child = {
name:"jone",
sex:"boy",
}
var kid = extenddeep(parent, child);
console.log(kid); // {name: "papa"
num: Array[3]
say: ()
sex: "boy"
// }
console.log(kid.say === parent.say); //true
console.log(kid.num === parent.num); //false
console.log(kid.name); //papa
var one = {
name:"object",
say: function(greet){
return greet + ', ' + this.name;
}
}
var tow = {
name:"two"
}
one.say.call(tow, "hi"); //hi, two
//赋值给一个变量时候上下文会变化
var say = one.say;
console.log(say('hoho')); // "hoho, undefined"
//作为回调函数时也会发生变化
var yetother = {
name:"yetother obj",
method:function(callback){
return callback("Hola");
}
}
console.log(yetother.method(one.say)); //"Hola, "
function bind(o, m){
return function(){
return m.apply(o, [].slice.call(arguments));
}
}
var othersay = bind(yetother, one.say);
othersay("Hola"); //"Hola, yetother obj"
//这段是直接复制过来的。
// ECMAScript 5给Function.prototype添加了一个bind()方法,以便很容易使用apply()和call()。
if (typeof Function.prototype.bind === 'undefined') {
Function.prototype.bind = function (thisArg) {
var fn = this,
slice = Array.prototype.slice,
args = slice.call(arguments, 1);
return function () {
return fn.apply(thisArg, args.concat(slice.call(arguments)));
};
};
}
var twosay2 = one.say.bind(two);
console.log(twosay2('Bonjour')); // "Bonjour, another object"
var twosay3 = one.say.bind(two, 'Enchanté');
console.log(twosay3()); // "Enchanté, another object"
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false ;
// Handle a deep copy situation
//如果第一个参数是boolean类型
//修正参数,将第二个参数作为target
if ( typeof target === "boolean" ) {
deep = target;
// skip the boolean and the target
target = arguments[ i ] || {};
//i++是为了后续 i === length的判断
i++;
}
// Handle case when target is a string or something (possible in deep copy)
//如果目标既不是对象也不是方法(例如给基本类型扩展属性方法和属性不会报错但是是无用的),修正target为 js对象
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// extend jQuery itself if only one argument is passed
//如果只有一个参数,修正对象为JQuery函数或JQuery对象
if ( i === length ) {
target = this ;
//修正target所在位置,后面的都是要添加给target的对象
i--;
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
//如果target和copy是同一个对象,略过,防止自己的属性引用了本身对象导致的循环引用,以致GC无法回收
if ( target === copy ) {
continue ;
}
// Recurse if we're merging plain objects or arrays
//如果是deep为true,并且要添加给target的copy为对象获数组
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false ;
clone = src && jQuery.isArray(src) ? src : [];
} else {
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
//很巧妙 ,用一个递归,实现引用对象的深克隆,递归的返回条件是属性石基本类型,基本类型都是深克隆
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
//浅克隆
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
};
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有