js继承机制

grid - 网格,布局

layout - 布局

  

  最近百度搜的比较勤,可是结果往往叫人失望,尽是些转来转去的文章,说的东西不一定正确之外,还要啰啰嗦嗦的长篇大论。我是厌恶别人长篇大论的,不管什么东西,应当有道理,踪迹可寻。前些天坐车的时候,某位男士说,“夸人要具体”, 那么不管是什么复杂的事物,都得具体!

  于是乎,之前的同事在学English, 而 碰巧 51CTO 出来篇文章说中国的技术落后西方两年, 首先要英语好技术高手弄通了人家的技术,在翻译,再出版,时间间隔的确很长。而且 本来在搜索 rgb 透明度的我, 碰巧看到一个 haslayout 的文章。于是,就搜起layout 吧~ 首先是英文的web ,呜呜 看不懂啊 勉强看了一点, 然后终于看到 “既是安安” 的博客上也有相关的主题。 Soga ,就是翻译的刚才那一篇! 

  之前经过测试 知道 span 标签 position:abosulute; 或者 float:left; 之后可以设置width, height 了。今天才知道是layout 的效果。

  但是, 我觉得学好英语真的是很重要, 之前是为了高考, 现在是实际需要的时刻, 若是中国人也讲的是英语, 在变成方面或许会更甚一筹,中国人是很聪明的。所以,之后的每天多学点English 吧 for myself (*^__^*) ...

  一个星期前就想着, 整理下 Javascript 继承 的, 很多面试的时候会问到这个东西。我很清楚, 就算我现在再把所有的继承的方式再敲一遍代码, 不久之后的我还是会忘记,所以, 我会经常温故的。

  以下内容参考 : http://www.w3cfuns.com/thread-1086-1-1.html

 一:继承的演变

1.WD构造函数:

function WD(skill){
    this.skill = skill;  
}
var WD1 = new WD('html');
console.log(WD1.skill); // html

在构造函数中的this关键字,它其实代表的是新创建的实例对象.

2. new 出来对象的缺陷

function WD(skill){
        this.skill = skill;
        this.sex = '男';
}

然后生成两个实例对象:

var WD1 = new WD('html');
var WD2 = new WD('css');

这两个对象的skill属性是独立的,修改其中一个,不会影响到另一个。

WD1.skill= 'Javascript';
console.log(WD2.skill);//“css”,不受WD1的影响

每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费

3.引入prototype属性

  为了实现属性和方法的共享,Brendan Eich决定为构造函数设置一个prototype属性。
这个属性包含一个对象(以下简称”prototype对象”),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面
实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。
还是以WD构造函数为例,现在用prototype属性进行改写:

function WD(skill){
        this.skill = skill;
}

WD.prototype = { sex : '男' };

var WD1 = new WD('html');
var WD2 = new WD('css');

console.log(WD1.sex); //
console.log(WD2.sex); //

  sex属性放在prototype对象里,是两个实例对象共享的。只要修改了prototype对象,就会同时影响到两个实例对象

WD.prototype.sex = '女';
console.log(WD1.sex); //
console.log(WD2.sex); //

  由于所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像”继承”了prototype对象一样。这就是Javascript继承机制的设计思想。

二:继承的实现方法

1. apply 或者call 绑定构造函数实现

function Woman(place){
    this.place = "Earth";
}

function Man(skill,sex){

    Woman.apply(this, arguments);
    //Woman.call(this,skill,sex)

    this.skill = skill;
    this.sex = sex;
}

var Man1 = new Man("Html","男");
console.log(Man1.place); // "Earth"

  apply 跟 call 都可实现继承,两者的区别是什么

  applly 直接传入参数 arguments 即可, call 需要传入所有的参数!

2.原型链prototype 实现

function Woman(place){
    this.place = "Earth";
}

function Man(skill,sex){
        this.skill = skill;
        this.sex = sex;
}
Man.prototype = new Woman();//Man的prototype 指向 Woman 的一个实例
Man.constructor = Man;
var Man1 = new Man("Html","男");
console.log(Man1.place); // "Earth"

  这句:

  Man.prototype = new Woman(); 相当于删除了原来的prototype 对象,重写了prototype 。
  Man.constructor = Man; 任何对象都有一个prototype 对象, 指向它的constructor .  记得前些日子看的一张图,很复杂的一张图! __proto__ 是内置原型 ,prototype 是 构造函数的原型对象。
  编程时,务必谨记,如果替换了prototype 对象,那么下一步必然是为新的prototype对象加上constructor属性

3. 从prototype直接继承实现  

  

 1     function Woman(){
 2     }
 3     Woman.prototype.show = "beauty";
 4 
 5     function Man(skill,sex){
 6             this.skill = skill;
 7             this.sex = sex;
 8     }
 9     Man.prototype = Woman.prototype;//Man的prototype 指向 Woman 的一个实例
10     Man.constructor = Man;
11     var Man1 = new Man("Html","男");
12     console.log(Man1.show);

  与前一种方法相比,这样做的优点是效率比较高(不用执行和建立MED的实例了),比较省内存。缺点是 WD.prototype和MED.prototype现在指向了同一个对象,那么任何对WD.prototype的修改,都会反映到MED.prototype。

  所以,上面这一段代码其实是有问题的。

  Man.constructor = Man;这一句实际上把Woman.prototype对象的constructor属性也改掉了!console.log(Woman.prototype.constructor); //这里不是很明白,因为我的测试出来是没有变化的 0。0

  其他还有的方法如下:

 1     //S   YUI库实现继承的方法
 2     function extend(Child,Parent){
 3 
 4         var F = function(){};
 5 
 6         F.prototype = Parent.prototype;
 7         Child.prototype = new F();
 8         Child.prototype.constructor = Child;
 9     }
10     extend(WD,MED);
11     // //E   YUI库实现继承的方法
1     //S 拷贝继承实现
2     function extendCopy(Child,Parent){
3         var p = Parent.prototype;
4         var c = Child.prototype;
5         for(var i in p){
6             c = p;
7         }
8     }
9     //E 拷贝继承实现

  还有浅拷贝,深拷贝,后面补充上

  最后记一下我之前做的页面的一个div 水平垂直居中的, css 如下

.wrap{position:absolute;left:50%;top:50%;width:400px;height:400px;margin-left:-200px;margin-top:-200px;}

  这个师父告诉我的时候,我明明知道为什么这么做的,但是body 没有加position:relative; 属性。问下,说是可以加,可以不加。然后前些天同事在一起看

  document.body.clientHeight   

  document.body.scrollHeight

  document.documentElement.scroollHeight ...

  鼠标移到body 上面 ,当没有一屏的时候 ,高度是很少的, 突然就想到这个绝对定位的东东, 不是说相对于body 定位? 那么body 高度那么小, 还top:50%? 跑下面去?测试了真不是相对于Body 定位的。 这个时候是相对于屏幕定位的 ,为什么我也不知道!必须给 body,html{height:100%;position:relative;} 之后方可依旧居中!

  

这是从老外的web 找到的,就是说取最大值。 这里还有涉及到 offsetHeight的 。。下面会另外写 offsetX , offsetY , pageX , pageY , layerX, layerY 的具体含义。

疯癫不成狂,有酒勿可尝;世间良辰美,终成水墨白。
原文地址:https://www.cnblogs.com/chuyu/p/3157697.html