百度前端技术学院笔记-JavaScript

1. JavaScript基础

1.1 了解JavaScript是什么

JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。

组成部分

  • ECMAScript,描述了该语言的语法和基本对象。
  • 文档对象模型(DOM),描述处理网页内容的方法和接口。
  • 浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口。

1.2 如何在HTML页面加载JavaScript代码

  • 使用<script>标签容纳JavaScript代码

    1
    2
    3
    <script>
    init();
    </script>
  • 使用< script src=”xxx.js”>< /script>外链方式引入

1
<script src="js/main.js"></script>
  • html界面元素直接赋与一段 JavaScript 代码
    1
    <input type="button" name="Button" value="Button" onclick="javascript:alert('测试')">

1.3 为什么要把< script>放在< /body>前面?

  • script标签放在底部的好处:
    虽然理论上放在哪里都是可以的,但是对于前端页面优化来讲,还是放在底部是最佳的,因为如果JS执行出现错误了,最起码页面中的元素还能加载出来,因为DOM文档是从上往下的顺序执行的。如果还不了解DOM的加载顺序,请阅读jQuery中ready与load事件的区别
    DOM文档加载的顺序:

    (1) 解析HTML结构。
    (2) 加载外部脚本和样式表文件。
    (3) 解析并执行脚本代码。
    (4) 构造HTML DOM模型。//ready
    (5) 加载图片等外部文件。
    (6) 页面加载完毕。//load

    ready事件:
    ready事件在DOM结构绘制完成之后就绘执行。这样能确保就算有大量的媒体文件没加载出来,JS代码一样可以执行。
    load事件:
    load事件必须等到网页中所有内容全部加载完毕之后才被执行。如果一个网页中有大量的图片的话,则就会出现这种情况:网页文档已经呈现出来,但由于网页数据还没有完全加载完毕,导致load事件不能够即时被触发。
    区别:
    其实如果页面中要是没有图片之类的媒体文件的话ready与load是差不多的,但是页面中有文件就不一样了,所以还是推荐大家在工作中用ready。

  • 应该放在底部的哪里:
    许多人认为只要放在底部了,无论是“body标签闭合之前”还是在“body标签闭合之后”都是一样的,其实还是有差别的,
    因为从HTML 2.0起放在“body标签闭合之后”就是不合标准的。之所以但是浏览器却不会报错,是因为如果在“body标签闭合之后”后再出现script或任何元素的开始标签, 都是parseerror,浏览器会忽略之前的,即视作仍旧在body内。所以实际效果和写在“body标签闭合之前”之前是没有区别的。
    所以,只要是让浏览器做了多余的事都是不好的,虽然差别细微,但是咱们还是按照标准来,放在body标签闭合之前

1.4 参考资料:JavaScript的性能优化:加载和执行

2. JavaScript数据类型及语言基础

2.1 任务描述

JavaScript数据类型(七种):

字符串、数字、布尔、数组、对象、Null、Undefined
参考资料:W3school JavaScript数据类型

2.1.1 判断各种数据类型的方法:

数据类型判断之 typeof

typeof可以解决大部分的数据类型判断,是一个一元运算,放在一个运算值之前,其返回值为一个字符串,该字符串说明运算数的类型,所以判断某个是否为String类型,可以直接 if(typeof(你的值) == "string"){}

1
2
3
4
5
6
7
8
9
10
var a="string"; console.log(a); //string
var a=1; console.log(a); //number
var a=false; console.log(a); //boolean
var a; console.log(typeof a); //undfined

var a = null; console.log(typeof a); //object
var a = document; console.log(typeof a); //object
var a = []; console.log(a); //object

var a = function(){}; console.log(typeof a) //function 除了可以判断数据类型还可以判断function类型

这样一来就很明显了,除了前四个类型外,null、对象、数组返回的都是object类型;对于函数类型返回的则是function,再比如typeof(Date)typeof(eval)等。然后这里就可以再引申出另一个灰常热门并且解决方法已普遍存在的问题,如何判断数据是个数组类型?

js判断数组类型的方法
方法一: instanceof

instance,故名思义,实例,例子,所以instanceof 用于判断一个变量是否某个对象的实例,是一个三目运算式—-和typeof最实质上的区别

1
a instanceof b?alert("true"):alert("false") //注意b值是你想要判断的那种数据类型,不是一个字符串,比如Array

方法二: constructor

在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用就是返回对象相对应的构造函数。从定义上来说跟instanceof不太一致,但效果都是一样的如:

1
2
(a instanceof Array)   //a是否Array的实例?true or false
(a.constructor == Array) // a实例所对应的构造函数是否为Array? true or false

注意:
使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array == object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;切记,不然很难跟踪问题!

方法三:最简单Object.prototype.toString.call

ECMA中对Object.prototype.toString的解释:

Object.prototype.toString( )
1.If the this value is undefined, return “[object Undefined]”.
2.If the this value is null, return “[object Null]”.
3.Let O be the result of calling ToObject passing the this value as the argument.
4.Let class be the value of the [[Class]] internal property of O.
5.Return the String value that is the result of concatenating the three Strings “[object “, class, and “]”.

即当toString()方法调用时:

1.如果this的值为undefined,则返回”[object Undefined]”.
2.如果this的值为null,则返回”[object Null]”.
3.让O成为调用ToObject(this)的结果.
4.让class成为O的内部属性[[Class]]的值.
5.返回三个字符串”[object “, class, 以及 “]”连接后的新字符串.

ECMA中对Array有如下说明:

The [[Class]] property of the newly constructed object is set to “Array”.

因此我们用如下方式来检测数组:

1
2
3
function isArray(arr) { 
return Object.prototype.toString.call(arr) === '[object Array]';
}

这种方式既解决了instanceof存在的跨页面问题,也解决了属性检测方式所存在的问题,是一个很好的解决方案。
除此之外,这种解决办法也可以应用于判断Date,Function等类型的对象。
附:ES5可以直接使用Array.isArray()来判断.
参考资料:
MDN对 说明:MDN-Object.prototype.toString()
ECMA5.1说明: ECMA5.1-Object.prototype.toString()
最新的ES6对Object.prototype.toString()的说明有所增加:ES6-Object.prototype.toString().不过变化不大,有兴趣的读者可以细看.

js判断函数类型方法

参考上面的方法,可以使用Object.propotype.toString.call来判断目标对象是否为函数.

1
2
3
4
// 判断fn是否为一个函数,返回一个bool值
function isFunction(fn) {
return Object.propotype.toString.call(fn) === "[object Function]";
}

关于=====的区别,参见 :javascript ==和===的区别