__proto__、prototype与原型链

关键词:__proto__,prototype,Object.create(),instanceof

1. __proto__(隐式原型)与prototype(显式原型)

显式原型(explicit prototype property):
几乎每一个函数(通过Function.prototype.bind方法构造出来的函数是个例外)在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。

隐式原型(implicit prototype link):
JavaScript中任意对象都有一个内置属性[[prototype]],可以通过.__proto__,或者通过符合ES5标准的Get方法Object.getPrototypeOf() 来访问。

为了介绍二者之间的关系,先上一张图:
prototype
根据ECMA定义__proto__的指向 to the value of its constructor’s “prototype”(其constructor的显式原型),所以我们来看图中:

more >>

NodeList和HTMLCollection

1.NodeList

通过各种方法获得的NodeList是一种类数组的对象,保存一组有序的节点,虽然我们可以使用一些数组的方法,但既然有个”类”字,显然它不是一个Array实例。

嗯,这些废话你应该都知道,虽然可能只是知道这个结果,却并不知道为什么。没关系,因为你现在看了这篇文章。

首先,JavaScript 的继承机制是基于原型的。
数组元素调用的数组方法,实际上是继承自它的原型链上。
myArray –> Array.prototype –> Object.prototype –> null
forEach等等数组方法,实际上是Array.prototype对象的方法。

而我们再来看NodeList的原型链
myNodeList –> NodeList.prototype –> Object.prototype –> null

NodeList.prototype 只有一个 item 方法,并没有 Array.prototype 上的那些方法。

当然,如果很想用数组方法来操作NodeList时,我们可以采用以下方法:

var forEach = Array.prototype.forEach;
var divs = document.getElementsByTagName( 'div' );
var firstDiv = divs[ 0 ];
forEach.call(firstDiv.childNodes, function( divChild ){
  divChild.parentNode.style.color = '#0F0';
});

2. NodeList是动态的?

more >>

绝对居中(Absolute Centering)

我们经常使margin:0 auto来实现水平居中,很多人在刚接触前端时都会有这样的疑问,为什么margin:auto 0不能实现垂直居中?
我们来看W3C对margin的部分描述:

If ‘margin-top’, or’margin-bottom’ are ‘auto’, their used value is 0.

可以理解为在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0;margin-bottom:0。
但是我们可以用以下代码实现垂直居中:

.ac{
    margin: auto;
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
}

此方法即是Absolute Centering。详细内容的英文原文可以参见Absolute Centering

绝对居中的实现原理:

“其实在接触到一样新方法时,知道其中的实现原理远比知道如何用重要的多。”

——沃兹基硕德

绝对居中(Absolute Centering)的工作机理可以总结如下:

more >>

理解BFC与haslayout

一、BFC定义

BFC全称Block Formatting Context,即”块级格式化上下文”。
Box 是 CSS 布局的对象和基本单位, 。一个页面是由很多个Box组成的。元素的类型和 display 属性,决定了这个Box的类型。 不同类型的 Box, 会参与不同的Formatting Context,因此Box内的元素会以不同的方式渲染。

Formatting context
Formatting context 是CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC),CSS3中还增加了GFC和FFC。

二、BFC布局规则:

  1. 内部的Box会在垂直方向,一个接一个地放置;
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠;
  3. 每个元素的margin box的左边, 与包含块border; box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
  4. BFC的区域不会与float box重叠;
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此;
  6. 计算BFC的高度时,浮动元素也参与计算。

三、生成BFC的条件和规则

满足如下条件一条或多条即会生成BFC:

  1. 根元素
  2. float属性不为none
  3. position为absolute或fixed
  4. display为inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不为visible;

四、BFC的作用及原理

more >>

JavaScript类数组

JavaScript中常见的类数组有arguments,NodeList和HTMLCollection等。
那它们有什么共性呢?如何判定一个对象是否属于类数组呢?

判定类数组

《JavaScript权威指南》上给出了代码用来判断一个对象是否属于“类数组”。代码如下:

// Determine if o is an array-like object.
// Strings and functions have numeric length properties, but are
// excluded by the typeof test. In client-side JavaScript, DOM text
// nodes have a numeric length property, and may need to be excluded
// with an additional o.nodeType != 3 test.
function isArrayLike(o) {
    if (o &&                                // o is not null, undefined, etc.
        typeof o === 'object' &&            // o is an object
        isFinite(o.length) &&               // o.length is a finite number
        o.length >= 0 &&                    // o.length is non-negative
        o.length===Math.floor(o.length) &&  // o.length is an integer
        o.length < 4294967296)              // o.length < 2^32
        return true;                        // Then o is array-like
    else
        return false;                       // Otherwise it is not
}

其实这种判断方式属于一种鸭式辨型(duck typing):如果它走起来像鸭子,叫起来也像鸭子的话,那它就是鸭子。所以对于类数组,只要满足下面这个条件我们即认为其为类数组:
具有length属性,且length值为大于等于0的整数。

类数组表现

more >>

我是王浩然,15年毕业于合肥工业大学,现就职于趣分期。</br>乐于分享,喜欢折腾。