Thursday, June 26, 2014

Javascript: Comparing undefined and null Values

大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的None,Ruby语言的nil。
有点奇怪的是,JavaScript语言居然有两个表示"无"的值:undefined和null。这是为什么?
undefined vs. null

一、相似性

在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别。

var a = undefined;

var a = null;

上面代码中,a变量分别被赋值为undefined和null,这两种写法几乎等价。
undefined和null在if语句中,都会被自动转为false,相等运算符甚至直接报告两者相等。

if (!undefined) 
    console.log('undefined is false');
// undefined is false

if (!null) 
    console.log('null is false');
// null is false

undefined == null
// true

上面代码说明,两者的行为是何等相似!
既然undefined和null的含义与用法都差不多,为什么要同时设置两个这样的值,这不是无端增加JavaScript的复杂度,令初学者困扰吗?Google公司开发的JavaScript语言的替代品Dart语言,就明确规定只有null,没有undefined!

二、历史原因

最近,我在读新书《Speaking JavaScript》时,意外发现了这个问题的答案!
原来,这与JavaScript的历史有关。1995年JavaScript诞生时,最初像Java一样,只设置了null作为表示"无"的值。
根据C语言的传统,null被设计成可以自动转为0。

Number(null)
// 0

5 + null
// 5

但是,JavaScript的设计者Brendan Eich,觉得这样做还不够,有两个原因。
首先,null像在Java里一样,被当成一个对象。但是,JavaScript的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich觉得表示"无"的值最好不是对象。
其次,JavaScript的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich觉得,如果null自动转为0,很不容易发现错误。
因此,Brendan Eich又设计了一个undefined。

三、最初设计

JavaScript的最初版本是这样区分的:null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

Number(undefined)
// NaN

5 + undefined
// NaN

四、目前的用法

但是,上面这样的区分,在实践中很快就被证明不可行。目前,null和undefined基本是同义的,只有一些细微的差别。
null表示"没有对象",即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype)
// null

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。

var i;
i // undefined

function f(x){console.log(x)}
f() // undefined

var  o = new Object();
o.p // undefined

var x = f();
x // undefined

(完)

CSS: Layer on layer with z-index (Layers)

CSS operates in three dimensions - height, width and depth. We have seen the first two dimensions in previous lessons. In this lesson, we will learn how to let different elements become layers. In short, this means the order of which the elements overlap one another.
For that purpose, you can assign each element a number (z-index). The system is that an element with a higher number overlaps an element with a lower number.
Let us say we are playing poker and have a royal flush. Our hand can be presented in a way where each card has got a z-index:
Royal Flush
In this case, the numbers follow on another (1-5) but the same result can be obtained by using 5 different numbers. The important thing is the chronological sequence of the numbers (the order).
The code in the card example could look like this:
 
 #ten_of_diamonds {
  position: absolute;
  left: 100px;
  top: 100px;
  z-index: 1;
 }

 #jack_of_diamonds {
  position: absolute;
  left: 115px;
  top: 115px;
  z-index: 2;
 }

 #queen_of_diamonds {
  position: absolute;
  left: 130px;
  top: 130px;
  z-index: 3;
 }

 #king_of_diamonds {
  position: absolute;
  left: 145px;
  top: 145px;
  z-index: 4;
 }

 #ace_of_diamonds {
  position: absolute;
  left: 160px;
  top: 160px;
  z-index: 5;
 }
 
 
The method is relatively simple but the possibilities are several. You can place images on text or text above text etc.

Summary

Layers can be used in many situations. For example, try to use z-index to create effects in headlines instead of creating these as graphics. For one thing, it is faster to load text and for another, it provides a potentially better ranking in search engines.

CSS: Positioning of elements

With CSS positioning, you can place an element exactly where you want it on your page. Together with floats (see lesson 13), positioning gives you many possibilities to create an advanced and precise layout.
The following will be discussed in this lesson:

The principle behind CSS positioning

Imagine a browser window as a system of coordinates:
Browserwindow with coordinates
The principle behind CSS positioning is that you can position any box anywhere in the system of coordinates.
Let's say we want to position a headline. By using the box model (see lesson 9) the headline will appear as follows:
Headline in a box
If we want this headline positioned 100px from the top of the document and 200px from the left of the document, we could type the following in our CSS:
 
 h1 {
  position:absolute;
  top: 100px;
  left: 200px;
 }
 
 
The result will be as follows:
Headline positioned in browserwindow
As you can see, positioning with CSS is a very precise technique to place elements. It is much easier than trying to use tables, transparent images or anything else.

Absolute positioning

An element which is positioned absolute does not obtain any space in the document. This means that it does not leave an empty space after being positioned.
To position an element absolutely, the position property is set as absolute. You can subsequently use the properties left, right, top, and bottom to place the box.
As an example of absolute positioning, we choose to place 4 boxes in each corner of the document:
 
 #box1 {
  position:absolute;
  top: 50px;
  left: 50px;
 }

 #box2 {
  position:absolute;
  top: 50px;
  right: 50px;
 }

 #box3 {
  position:absolute;
  bottom: 50px;
  right: 50px;
 }

 #box4 {
  position:absolute;
  bottom: 50px;
  left: 50px;
 }
 
 

Relative positioning

To position an element relatively, the property position is set as relative. The difference between absolute and relative positioning is how the position is being calculated.
The position for an element which is relatively positioned is calculated from the original position in the document. That means that you move the element to the right, to the left, up or down. This way, the element still obtains a space in the document after it is positioned.
As an example of relative positioning, we can try to position three pictures relatively to their original position on the page. Notice how the pictures leave empty spaces at their original positions in the document:
 
 #dog1 {
  position:relative;
  left: 350px;
  bottom: 150px;
 }
 #dog2 {
  position:relative;
  left: 150px;
  bottom: 500px;
 }

 #dog3 {
  position:relative;
  left: 50px;
  bottom: 700px;
 }
 
 

CSS: Floating elements (floats)

An element can be floated to the right or to left by using the property float. That is to say that the box with its contents either floats to the right or to the left in a document (or the containing box) (seelesson 9 for a description of the Box model). The following figure illustrates the principle:
A left-floating box
If we for example would like to have a text wrapping around a picture, the result would be like this:
A left-floating box with a picture and text wrapped around it

How is it done?

The HTML code for the example above, look as follows:
 
 
Bill Gates
causas naturales et antecedentes, idciro etiam nostrarum voluntatum...
To get the picture floating to the left and the text to surround it, you only have to define the width of the box which surrounds the picture and thereafter set the property float to left:
 
 #picture {
  float:left;
  width: 100px;
 }
 
 

Another example: columns

Floats can also be used for columns in a document. To create the columns, you simply have to structure the desired columns in the HTML-code with 
 as follows:
 
 
Haec disserens qua de re agatur et in quo causa consistat non videt...
causas naturales et antecedentes, idciro etiam nostrarum voluntatum...
nam nihil esset in nostra potestate si res ita se haberet...
Now the desired width of the columns is set to e.g. 33%, and then you simply float each column to the left by defining the property float:
 
 #column1 {
  float:left;
  width: 33%;
 }

 #column2 {
  float:left;
  width: 33%;
 }

 #column3 {
  float:left;
  width: 33%;
 }
 
 
float can be set as either left, right or none.

The property clear

The clear property is used to control how the subsequent elements of floated elements in a document shall behave.
By default, the subsequent elements are moved up to fill the available space which will be freed when a box is floated to a side. Look at the example above wherein the text is automatically moved up beside the picture of Bill Gates.
The property clear can assume the values left, right, both or none. The principle is, if clear, for example, is set to both for a box, the top margin border of this box will always be under the lower margin border for possible floating boxes coming from above.
 
 
Bill Gates

Bill Gates

class="floatstop"
>causas naturales et antecedentes, idciro etiam nostrarum voluntatum...
To avoid the text from floating up next to the picture, we can add the following to our CSS:
 
 #picture {
  float:left;
  width: 100px;
 }

 .floatstop {
  clear:both;
 }
 
 

CSS: The box model

The box model in CSS describes the boxes which are being generated for HTML-elements. The box model also contains detailed options regarding adjusting margin, border, padding and content for each element. The diagram below shows how the box model is constructed:

The box model in CSS


The illustration above might seem pretty theoretical to look at, so let's try to use the model in an actual case with a headline and some text. The HTML for our example is (from the Universal Declaration of Human Rights):
 
 

Article 1:

All human beings are born free and equal in dignity and rights. They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood
By adding some color and font-information the example could be presented as follows:
The example contains two elements: 

 and . The box model for the two elements can be illustrated as follows:
Even though it may look a bit complicated, the illustration shows how each HTML-element is surrounded by boxes. Boxes which we can adjust using CSS.

Margin and padding


Set the margin in an element

An element has four sides: right, left, top and bottom. The margin is the distance from each side to the neighboring element (or the borders of the document). See also the diagram in lesson 9 for an illustration.
As the first example, we will look at how you define margins for the document itself i.e. for the element . The illustration below shows how we want the margins in our pages to be.
Examples of margins
The CSS code for this would look as follow:
 
 body {
  margin-top: 100px;
  margin-right: 40px;
  margin-bottom: 10px;
  margin-left: 70px;
 }
 
 
Or you could choose a more elegant compilation:
 
 body {
  margin: 100px 40px 10px 70px;
 }
 
 
You can set the margins in the same way on almost every element. For example, we can choose to define margins for all of our text paragraphs marked with :
 
 body {
  margin: 100px 40px 10px 70px;
 }

 p {
  margin: 5px 50px 5px 50px;
 }
 
 

Set padding in an element

Padding can also be understood as "filling". This makes sense as padding does not affect the distance of the element to other elements but only defines the inner distance between the border and the content of the element.
The usage of padding can be illustrated by looking at a simple example where all headlines have background colors:
 
 h1 {
  background: yellow;
 }

 h2 {
  background: orange;
 }
 
 
By defining padding for the headlines, you change how much filling there will be around the text in each headline:
 
 h1 {
  background: yellow;
  padding: 20px 20px 20px 80px;
 }

 h2 {
  background: orange;
  padding-left:120px;
 }
 
 


Borders

Borders can be used for many things, for example as a decorative element or to underline a separation of two things. CSS gives you endless options when using borders in your pages.

The width of borders [border-width]

The width of borders is defined by the property border-width, which can obtain the values thin, medium, and thick, or a numeric value, indicated in pixels. The figure below illustrates the system:
Examples of border-width

The color of borders [border-color]

Colors
The property border-color defines which color the border has. The values are the normal color-values for example "#123456", "rgb(123,123,123)" or "yellow" .

Types of borders [border-style]

There are different types of borders to choose from. Below are shown 8 different types of borders as Internet Explorer 5.5 interprets them. All examples are shown with the color "gold" and the thickness "thick" but can naturally be shown in other colors and thicknesses.
The values none or hidden can be used if you do not want any border.
Different types of borders

Examples of defining borders

The three properties described above can be put together by each element and thereby produce different borders. To illustrate this, we will take a look at a document where we define different borders for 

, 

, 
     and . The result may not be that pretty but it illustrates some of the many possibilities:
     
     h1 {
      border-width: thick;
      border-style: dotted;
      border-color: gold;
     }
    
     h2 {
      border-width: 20px;
      border-style: outset;
      border-color: red;
     }
    
     p {
      border-width: 1px;
      border-style: dashed;
      border-color: blue;
     }
    
     ul {
      border-width: thin;
      border-style: solid;
      border-color: orange;
     }
     
     
    It is also possible to state special properties for top-, bottom-, right- or left borders. The following example shows you how:
     
     h1 {
      border-top-width: thick;
      border-top-style: solid;
      border-top-color: red;
    
      border-bottom-width: thick;
      border-bottom-style: solid;
      border-bottom-color: blue;
    
      border-right-width: thick;
      border-right-style: solid;
      border-right-color: green;
    
      border-left-width: thick;
      border-left-style: solid;
      border-left-color: orange;
     }
     
     

    Compilation [border]

    As it is also the case for many other properties, you can compile many properties into one using border. Let us take a look at an example:
     
     p {
      border-width: 1px;
      border-style: solid;
      border-color: blue;
     }
     
     
    Can be compiled into:
     
     p {
      border: 1px solid blue;
     }