js常识

数据类型

在 JavaScript 中有 5 中不同的数据类型:

 

    string

    number

    boolean

    object

    function

 

3 种对象类型:

 

    Object

    Date

    Array

 

2 个不包含任何值的数据类型:

 

    null

    undefined

 

 

 

 

你可以使用 typeof 操作符来查看 JavaScript 变量的数据类型。

实例

typeof "John"                 // 返回 string

typeof 3.14                   // 返回 number

typeof NaN                    // 返回 number

typeof false                  // 返回 boolean

typeof [1,2,3,4]              // 返回 object

typeof {name:'John', age:34}  // 返回 object

typeof new Date()             // 返回 object

typeof function () {}         // 返回 function

typeof myCar                  // 返回 undefined (if myCar is not declared)

typeof null                   // 返回 object

 

请注意:

 

    NaN 的数据类型是 number

    数组(Array)的数据类型是 object

    日期(Date)的数据类型为 object

    null 的数据类型是 object

    未定义变量的数据类型为 undefined

 

如果对象是 JavaScript Array 或 JavaScript Date ,我们就无法通过 typeof 来判断他们的类型,因为都是 返回 Object。

解决方法:

判断是否是数组

myArray.constructor.toString().indexOf("Array") > -1;

判断是否是日期

myDate.constructor.toString().indexOf("Date") > -1;

 

arguments caller callee

arguments 的完整语法如下:

[function.]arguments[n]

参数function :选项。当前正在执行的 Function 对象的名字。 n :选项。要传递给 Function 对象的从0开始的参数值索引。

 

在一个函数调用另一个函数时,被调用函数会自动生成一个caller属性,指向调用它的函数对象。如果该函数当前未被调用,或并非被其他函数调用,则caller为null。

 

当函数被调用时,它的arguments.callee对象就会指向自身,也就是一个对自己的引用。

由于arguments在函数被调用时才有效,因此arguments.callee在函数未调用时是不存在的(即null.callee),且解引用它会产生异常。

 

var foo = function bar() {

   // statements go here

};

在这个函数体内,以下的语句是等价的:

bar()

arguments.callee()

foo()

 

嵌套函数和闭包

你可以在一个函数里面嵌套另外一个函数。嵌套(内部)函数是容器(外部)函数的私有成员。它自身也形成了一个闭包。一个闭包是一个可以自己拥有独立的环境与变量的的表达式(通常是函数)。

既然嵌套函数是一个闭包,就意味着一个嵌套函数可以继承容器函数的参数和变量。换句话说,内部函数包含外部函数的作用域。

可以总结如下:

    内部函数只可以在外部函数中访问

    内部函数形成了一个闭包:它可以访问外部函数的参数和变量,但是外部函数却不能使用它的参数和变量

 

function outside(x) {

  function inside(y) {

    return x + y;

  }

  return inside;

}

// Think of it like: give me a function that adds 3 to whatever you give it

fn_inside = outside(3);

console.log(fn_inside);

result = fn_inside(5); // returns 8

console.log(result);

result1 = outside(3)(5); // returns 8

console.log(result1)

保存变量

注意到上例中inside被返回时x是怎么被保留下来的。一个闭包必须保存它可见作用域中所有的参数和变量。因为每一次调用传入的参数都可能不同,每一次对外部函数的调用都实际上重新创建了一遍这个闭包。只有当inside的返回值没有再被引用时,内存才会被释放。

这与存储在其他对象的引用不同,而且通常是不太明显的,因为并不能直接设置引用,且不能检查(inspect)它们。

 

细节

1、switch 语句会使用恒等计算符(===)进行比较

2、字符串断行需要使用反斜杠(\)

3、

JavaScript 不支持使用名字来索引数组,只允许使用数字索引。

实例

var person = [];

person[0] = "John";

person[1] = "Doe";

person[2] = 46;

var x = person.length;         // person.length 返回 3

var y = person[0];             // person[0] 返回 "John"

 

在 JavaScript 中, 对象 使用 名字作为索引。

 

如果你使用名字作为索引,当访问数组时,JavaScript 会把数组重新定义为标准对象。

 

执行这样操作后,数组的方法及属性将不能再使用,否则会产生错误:

实例

var person = [];

person["firstName"] = "John";

person["lastName"] = "Doe";

person["age"] = 46;

var x = person.length;         // person.length 返回 0

var y = person[0];             // person[0] 返回 undefined

 

4、

Undefined 不是 Null

 

在 JavaScript 中, null 用于对象, undefined 用于变量,属性和方法。

 

对象只有被定义才有可能为 null,否则为 undefined。

 

如果我们想测试对象是否存在,在对象还没定义时将会抛出一个错误。

 

错误的使用方式:

 

if (myObj !== null && typeof myObj !== "undefined")

 

正确的方式是我们需要先使用 typeof 来检测对象是否已定义:

 

if (typeof myObj !== "undefined" && myObj !== null)

 

5、JavaScript 闭包

 

还记得函数自我调用吗?该函数会做什么?

实例

var add = (function () {

    var counter = 0;

    return function () {return counter += 1;}

})();

 

add();

add();

add();

 

// 计数器为 3

实例解析

 

变量 add 指定了函数自我调用的返回字值。

 

自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。

 

add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。

 

这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。

 

计数器受匿名函数的作用域保护,只能通过 add 方法修改。

 

6、事件冒泡或事件捕获?

 

事件传递有两种方式:冒泡与捕获。

 

事件传递定义了元素事件触发的顺序。 如果你将 <p> 元素插入到 <div> 元素中,用户点击 <p> 元素, 哪个元素的 "click" 事件先被触发呢?

 

在 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素,即: <p> 元素的点击事件先触发,然后会触发 <div> 元素的点击事件。

 

在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即: <div> 元素的点击事件先触发 ,然后再触发 <p> 元素的点击事件。

 

addEventListener() 方法可以指定 "useCapture" 参数来设置传递类型:

addEventListener(event, function, useCapture);

 

默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递。

实例

document.getElementById("myDiv").addEventListener("click", myFunction, true);

 

 

跨浏览器解决方法:

var x = document.getElementById("myBtn");

if (x.addEventListener) {                    // 所有主流浏览器,除了 IE 8 及更早版本

    x.addEventListener("click", myFunction);

} else if (x.attachEvent) {                  // IE 8 及更早版本

    x.attachEvent("onclick", myFunction);

}

 

7、Window 尺寸

 

有三种方法能够确定浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)。

 

对于Internet Explorer、Chrome、Firefox、Opera 以及 Safari:

 

    window.innerHeight - 浏览器窗口的内部高度

    window.innerWidth - 浏览器窗口的内部宽度

 

对于 Internet Explorer 8、7、6、5:

 

    document.documentElement.clientHeight

    document.documentElement.clientWidth

 

或者

 

    document.body.clientHeight

    document.body.clientWidth

 

实用的 JavaScript 方案(涵盖所有浏览器):

实例

var w=window.innerWidth

|| document.documentElement.clientWidth

|| document.body.clientWidth;

 

var h=window.innerHeight

|| document.documentElement.clientHeight

|| document.body.clientHeight;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值