简单的静态网页Demo

  1. 弹幕网站

    danmu

  2. 名人名言

    phrase

    这是一个月以前做的小项目,把它们部署到了Coding上。适合前端小白用于练手。解析域名的时候很玄学,

quotes 死活不行,换成 phrase 就可以了。真的好笑~

看书和看视频学习那个会更好?

前言

说来惭愧,我回老家已经90天了,要学习的东西仍没些成就,每日晚睡晚起,实在懒散。前面看《JavaScript高级程序设计》边做笔记边看吧太慢,在医院的时候没电脑实践时不能消化。这是其一,其二是作者老是说些繁枝莫节,或者说是介绍的太过详细。你如果也看过写大部头就知道这种烦恼了。随后我想起下过 智能社 blue 老师讲的《JavaScript视频》,就在b站重新下了份,一股劲看了10/32 。看的时候有一些疑问和感想,记在了便利贴上,拖了几日,这才补上。

<script> 标签应该放在那里?

在红宝书中,尼古拉斯建议读者将其放在body 元素中页面内容的后面,原因是放在head 中,网页会下载完JavaScript代码后才显示html ,对于需要很多JavaScript代码的页面,会出现明显的延迟。
尼古拉斯提出的方法你可以在火狐浏览器的火狐主页中看到,你可以先看到先出现一些HTML,之后页面才会加载样式出来,这样一来会带来不好的用户体验。
石川老师写JS的时候,将script标签方法了head中,并使用了window.onload函数,这会使得html加载完之后再加载JS。但这样也有它的缺点,即当js中的代码过多时,会出现用户无法触发事件的尴尬状况。
那么script到底应该放在那里呢?
最好的解决办法应该是 <script> 的 延迟(defer)和 异步(async)属性来解决,但我没有具体的实践经验,因此现在 只好 “纸上谈兵” 了

Function 算是什么类型?

单纯的只论类型的话,是Object 类型。

匈牙利命名法对前端有无必要?前端的命名规范是什么?

没有必要。

  1. 匈牙利命名法是从静态语言发展而来,而JavaScript的变量是弱类型,变量可能会在变量定义后发生类型的改变,从而导致不必要的错误。
  2. 经过实践,我看过一些淘宝和百度的js 文件并没有发现这一命名法的应用,说明 JS 中匈牙利命名法是小众的行为。
  3. 总结是:是否采用匈牙利命名法要取决于你所在公司团队的习惯、其他的编程习惯也是如此。

this 关键字的应用

  1. 控件中的使用。
  2. 构造函数里,充当隐形的 实例。

    什么是重点?

    依靠自己的经验、不断总结慢慢知道的。

    视频和看书

  3. 视频见效快、
  4. 看书基础牢固
  5. 全局变量属于window还是Global 对象?

bolg

前期写blog的时候别要求太多,快速的的写完就是了,不要怕错。另一点是不要想的 事事完美这是不可能的,只当是记录就行了。

红宝书阅读笔记ch5-3

红宝书阅读笔记ch5-3

单体内置对象(Global对象和Math对象)

单体内置对象

啥叫单体内置对象?
这要分成两部分来说,首先说下什么是内置对象?内置对象的定义是:“由ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了。”意思是开发人员不必实例化内置对象,因为它们已经实例化了。例如Object、Array和String。
根据前面对内置对象的理解,单体内置对象按我的理解即整个程序中只有一个的内置对象就是单体内置对象,写法就是不用实例化的而且只有一个的对象,可以直接使用这个对象的方法。

Global 对象

Global (全局)对象,是ECMAScript对象中最特别的一个对象了,因为你根本看不见它,但是它确实是存在的,不属于其他对象的属性和方法,都是它的的属性和方法。事实上,没有全局函数和全局变量;所有在全局作用域中的定义的属性和函数,都是Global 对象的属性。例如 parseFloat ( )、isNaN( )、isFinite( )都是Global 对象的方法。
除此之外Global 对象还有其他的方法。

  1. URI 编码方法,要进行编码是因为有效的URI不能包括某些字符,如空格。
    1. encodeURI( ),应用整个URI,将空格编码成 %20 ,除此之外其他不变
    2. encodeURIComponent( ) ,应用URI中的某一段,将所有非字母和数字的字符进行编码替换。

  2. 解码方法
    1. decodeURI( ),对encodeURI( )进行解码,只会将%20 变成空格。
    2. decodeURIComponent( ),对encodeURIComponent( )进行解码,可以解任何特殊字符的编码。
    3. eval( ) 方法,接收一个参数,即要执行的ECMAScript字符串。 它的作用是解释代码字符串。

  3. Global 对象的属性

属性 说明 属性 说明
undefined 特殊值undefined Date 构造函数Date
NaN 特殊值NaN RegExp 构造函数RegExp
Infinity 特殊值Infinity Error 构造函数Error
Object 构造函数Object EvalError 构造函数EvalError
Array 构造函数Array RangeError 构造函数RangeError
Function 构造函数Function ReferenceError 构造函数ReferenceError
Boolean 构造函数Boolean SyntaxError 构造函数SyntaxError
String 构造函数String TypeError 构造函数TypeError
Number 构造函数Number URIError 构造函数URIError
  1. window 对象,Global全局对象作为window对象的一部分加以实现的。即Global属于window对象的一部分。

Math对象

ECMAScript为保存数学公式和信息提供了一个公共位置,即Math对象。与我们在JavaScript中直接编写的计算功能相比,Math对象提供的计算功能执行起来要快得多。

  1. Math 对象的属性

属性 说明
Math.E 自然对数的底数,即常量e的值
Math.LN10 10的自然对数
Math.LN2 2的自然对数
Math.LOG2E 以2为底e的对数
Math.LOG10E 以10为底e的对数
Math.PI π的值
Math.SQRT1_2 1/2的平方根
Math.2 2的平方根
  1. min( ) 和 max( ) 方法 ,得出一组数字中的最小值和最大值。

    1. 找到数组中的最大或最小值

var values=[1,2,3,4,5,6,7,8];
var max=Math.max.apply(Math,values);
alert(max);
  1. 舍入方法

    1. Math.ceil( ) ,执行向上舍入,取整数

    2. Math.florr( ),执行向下舍入,取整数

    3. Math.round( ),四舍五入,取整数

  2. random( ) 方法 ,返回一个大于等于0小于1的随机数。

    1. 取整数的公式
      值 = Math.floor( Math.random( ) * 可能值的总数 + 第一个可能的值 )

    2. 1到10之间的数值
      var num=Math.floor( Math.random() * 10 + 1 );

    3. 函数

function selectFrom(lowerValue, upperValue) {
var choices = upperValue - lowerValue + 1;
return Math.floor(Math.random() * choices + lowerValue);
}
//取数组中的随机一项
var colors=["red","green","blue","black","purple","brown"];
var color=colors[selectFrom(0,colors.length-1)];
//取1到10之间的任意一个整数
var num=selectFrom(1,10);
  1. 其他方法

方法 说明 方法 说明
Math.abs(num) 返回num的绝对值 Math.asin(x) 返回x的反正弦值
Math.exp(num) 返回Math.E的num次幂 Math.atan(x) 返回x的反正切值
Math.log(num) 返回num的自然对数 Math.atan2(y,x) 返回有y,x的反正切值
Math.pow(num,power) 返回num的power次幂 Math.cos(x) 返回x的余弦值
Math.sqrt(num) 返回num的平方根 Math.sin(x) 返回x的正弦值
Math.acos(x) 返回x的反余弦值 Math.tan(x) 返回x的正切值

2019.12.20

红宝书阅读笔记ch5-2

红宝书阅读笔记ch5-2

Date类型、RegExp类型、Function类型、基本包装类型

Date类型

  1. Date类型保存的时间精度在1970年之前和之后的一亿年。

  2. 获取当前时间只要new一个Date就行了。

  3. 根据指定日期和时间来创建日期对象的方法有三种:

    1. 传入表示该日期的毫秒数(从1970到该日期所经过的毫秒数) 。

    2. Date.prese( ) ,传入 一个表示日期的字符串,然后该方法尝试返回一个相应日期的毫秒数。

    3. Date.UTC() ,传入一连串表示时间的数字,返回表示日期的毫秒数。

var now=new Date();//当前时间
var oneSecond=new Date(1000); //一秒
var prese=new Date(Date.parse("11/9/2019"));
//var prese=new Date("11/9/2019"); 和上面那句一毛一样
var utc=new Date(Date.UTC(2005,4,5,17,55,55));
//var utc=new Date(2005,4,5,17,55,55);
alert("当前时间:"+now);
alert("Date.parse(\"11/9/2019\"):"+prese);
alert("Date.UTC(2005,4,5,17,55,55):"+utc);
alert("一千毫秒"+oneSecond);
  1. Date.valueOf( ) ,返回日期的毫秒数,因此可以用来比较日期值。

var date1 = new Date(2007, 0, 1); //January 1, 2007
var date2 = new Date(2007, 1, 1); //February 1, 2007
alert(date1 < date2); //true
alert(date1 > date2); //false
  1. 日期格式化方法

var dateString =new Date(); //显示星期几、月、日、年
var timeString=new Date(); //显示时、分、秒和时区
var localeDateString=new Date(); //本地区的格式显示显示星期几、月、日、年
var utcString=new Date(); //完整的UTC日期
alert("dateString "+dateString.toDateString());
alert("timeString "+dateString.toTimeString());
alert("localeDateString "+dateString.toLocaleDateString());
alert("utcString "+dateString.toUTCString());
  1. 日期/时间的组件方法
    都是取得和设置日期中值的方法,还有很多方法没列,可上 MDN了解。

var now = new Date();
var time=now.getTime();
var fullYear=now.getFullYear();
var month=now.getMonth();

RegExp 类型

  1. 语法
    pattern(模式) ,是简单或复杂的正则表达式
    flags(标识),表示正则表达式的行为:
    g:全局模式;
    i:不区分大小写;
    m:表示多行。

var expression = / pattern / flags
  1. pattern 中使用的所有元字符都必须转义。
    () [] {} \ ^ $ | ? * + .

  2. RegExp构造函数
    pattern1和pattern2完全等价,但由于RegExp的参数是字符串,所以在使用元字符时都必须双重转义。

var pattern1=/ [bc]at /i;
var pattern2=new RegExp("[bc]at","i");
//匹配 [bc]at ,字面量是 / \[bc\]at /
var pattern3=new RegExp("\\[bc\\]at","i");
  1. RegExp的实例属性
    global:布尔值,表示是否设置了g标识,相似的还有ignoreCase、multiline,分别表示i、m标识。
    source:正则表达式的字符串表示
    lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从0算起。

  2. RegExp实例方法

    1. exec( ) ,参数是一个要匹配模式的字符串,没有匹配项时返回null,有匹配项时返回一个数组,第一项是与整个模式匹配的字符串, 第二项是与 RegExp的实例 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。
      对于exec( ) 方法而言,即是在模式中设置全局标识(g),它每次也只会返回一个匹配项。
      在不设置全局标志的情况下,在同一个字符串上多次调用exec( ) 将始终返回第一个匹配项的信息,而在设置全局标识的情况下,每次调用exec( ) 则都会在字符串中继续查找新匹配项。

    2. test( ) ,接收一个字符串参数,在模式与参数匹配的情况下返回true;否则返回false。

  3. RegExp构造函数属性
    RegExp构造函数包含一些属性(你可以认为这是RegExp类型的 “静态属性”)。这些属性适用与作用域中的所有正则表达式。这些属性分别有自己的长属性名和短属性名。

长属性名 短属性名 说明
input $_ 最近一次要匹配的字符串
lastMatch $& 最近一次匹配项
lastParen $+ 最近一次匹配的捕获组
leftContext $` input字符串中lastMatch之前的文本
multiline $* 布尔值,表示是否所有的表达式都使用多行模式
rightContext $’ input字符串中lastMatch之后的文本

Function 类型

  1. 函数实际上是一个对象。(函数是对象,函数名是指针

  2. 函数的三种语法

//函数声明语法
function sum(num1,num2){
return num1+num2;
}
//函数表达式
var sum=function(num1,num2){
return num1+num2;
}
//Function构造函数
//不推荐这种写法,不过它可以帮你理解 “函数是对象,函数名是指针” 的概念。
var sum=new Function("num1","num2","return num1+num2");
  1. 每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。

  2. 函数名实际上是一个指向函数对象的指针。

  3. JavaScript 没有重载。

  4. 函数声明在代码执行的顺序中优于函数表达式,原因是在代码开始执行之前,解析器就已经通过一个名为函数声明提升的过程,读取并将声明添加到执行环境中。对代码求值时,JavaScript 引擎在第一遍会声明函数并将它们放到源代码树的顶部。所以,即使声明函数的代码在调用它的代码后面,JavaScript 引擎也能把声明函数提示到顶部。

  5. 解析器在向执行环境中加载数据时,解析器会率先读取函数声明,并使其在执行任何代码之前可以访问;至于函数表达式,则必须等到解析器到它所在的代码行,才会真正被解释执行。

//函数声明,可以执行
alert(sum(10,10));
function sum(num1,num2){
return num1+num2;
}
//函数表达式,报错
alert(sum(10,10));
var sum=function (num1,num2){
return num1+num2;
}
  1. 要访问函数的指针而不执行函数的话,必须去掉函数名后面那对圆括号。

  2. 因为函数名本身就是变量,所以函数可以作为值来使用。第一你可以像传递参数一样把一个函数传递给另一个函数,第二你可以将函数作为另一个函数的结果返回。

  3. 函数内部的属性

    1. arguments.callee 该属性是一个指针,指向 拥有arguments对象的函数。(现在已逐渐淘汰,尽量不要用)

    2. arguments 是一个类数组的对象。

    3. this ,this引用的是函数执行的环境对象,当在网页的全局作用域中调用函数时this对象引用的就是window。

    4. caller ,这个属性中保存着调用当前函数的引用,如果是在全局作用域中调用当前函数,它的值为null。另外也可以通过 arguments.callee.caller 来访问该属性。

  4. 函数属性和方法

    1. function.object.length,表示函数希望接收的命名参数的个数。

    2. prototype ,引用类型的原型,用以保存引用类型实例方法。(之后的JavaScript的面向对象会重点提到,这里不做过多介绍。)

    3. apply( ) 和 call( ) 的用途都是在特定的作用域中调用函数,也可以理解为扩充函数作用域的方法。它们的区别只是在参数的传递上。

    4. bind( ) ,这个方法会创建一个函数的实例,其this值会被绑定到传给bind( )函数的值。

基本包装类型

  1. 基本包装类型即Boolean、Number和String。可以理解为Object 对布尔值、数值、字符串的包装类型。

  2. Number 的方法

    1. Number.toFixed( ) ,按照指定的小数位返回数值的字符串表示,适用于处理货币值。

    2. Number.toExponetial( ) ,以指数表示法返回数值的字符串形式。

    3. Number.toPrecision( ) ,根据表示数值所有数字的位数的参数,来返回不同的数值表示法。

  3. String 类型

    1. String.length ,返回字符串的字符数。

    2. String.charAt( ) ,参数是字符的length值,返回指定位置的字符。(实际上是字符串,因为JS没字符类型)

    3. String.charCodeAt( ) ,参数是字符的length值,返回指定位置的字符编码。

    4. String.concat( ) ,连接两个字符串。

    5. slicce( )、substr( )、substring( ) ,基于子字符串创建新的字符串的方法。

    6. indexOf( )、lastIndexOf( ) ,搜索给定的子字符串,返回子字符串的位置,一个从前往后,一个从后往前。

    7. trim( ) ,创建一个字符串的副本,删除前置和后缀的所有空格.

    8. 字符串大小写装换方法,toLowerCase( ) 、toLocalLowerCase( ) 、toUpperCase( ) 、toLocalUpperCase( ) 。

    9. match( ),参数是一个正则表达式或RegExp对象,返回匹配模式的数组。

    10. search( ),参数是一个正则表达式或RegExp对象,返回第一个匹配项的索引,没找到返回-1.

    11. replace( ),参数是第一个RegExp对象或是一个字符串(非正则表达式),第二个是用以替换的字符串或者是一个函数。

    12. split( ),基于指定的分隔符将一个字符串分割成多个字符串,并将结果放在一个数组里。第一个参数是分隔符,也可以是一个RegExp对象,第二个参数是数组的长度。

    13. String.localeCompare(str ),用于比较两个字符串,返回数字-1,0,1 。零是两个字符串相等,正一和负一表示参数的首字母在字符串之前或之后。这个方法不区分大小写。

2019.12.20

红宝书阅读笔记ch5-1

红宝书阅读笔记ch5-1

Object类型和Array类型

引用类型

  • 引用类型的值(对象)是引用类型的实例。可以理解成Java里的对象和类的关系。

  • 引用类型是一种数据结构,用于将数据和功能组织在一起。

Object类型

  • 创建Object的两种方式;

//第一种方式 new 操作符后跟Object构造函数
var person =new Object();
person.name="1n40";
person.age=21;
//第二种方式 对象字面量表示法
var person={
name:"1n40",
age:21
};
//使用对象字面量语法时,属性名也可以使用字符串
var person={
"name":"1n40",
"age":21,
5:true
};
//
var person={}; // 与 new Object()相同
person.name="1n40";
person.age=21;
  • 对象字面量也是向函数传递大量可选参数的首选方式;

function displayInfo(args) {
var output = "";
if (typeof args.name == "string"){
output += "Name: " + args.name + "\n";
}
if (typeof args.age == "number") {
output += "Age: " + args.age + "\n";
}
alert(output);
}
displayInfo({
name: "Nicholas",
age: 29
});
displayInfo({
name: "Greg"
});
  • 访问对象属性的两种方法:

    • 点表示法;

    • 方括号表示法。

    • 一般来说,访问对象属性时使用的都是点表示法,因为点表示法比方括号表示法更加简洁和方便,假如属性名中包含导致语法错误的字符,或者属性名使用了关键字和保留字,这时候使用方括号表示法更佳。

    • 通常我们一般推荐用点表示法。

    • 在通过对象字面量定义对象时,实际上不会调用Object 构造函数。

//功能上两种方法没有任何区别
alert(person["name"]);
alert(person.name);
//方括号表示法的优点是可以通过变量来访问属性,和访问一些有特殊字符的变量名
var propertyName="name";
alert(person[propertyName]); // 值是 “name”
//属性名包含空格,不能点出来
person["first name"]="1n40";

Array类型

  • Array类型的三个特点:

    • 有序列表;

    • 数组的每一项可以保存任何类型的数据;

    • 数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据。

  • 创建数组的基本方式有两种

//第一种使用Array构造函数
var colors=new Array();
var colors=new Array(20);
var colors=new Array("red","blue","green");
var colors=Array(); //可以省略new关键字,结果相同
//第二种方式是使用数组字面量表示法
var colors=["red","blue","green"];
var names=[];
var values=[1,2,]; //错误示范!这样会创建一个包含2或3项的数组(视浏览器而定)
var options=[,,,,,];//错误示范!这样会创建一个包含5或6项的数组(视浏览器而定)
  • 给构造函数传递一个值也可以创建数组,如果传递的是数值,则按照数值创建指定项数的数组,而如果传递的是非数值的参数,则创建一个包含那个值的只有一项的数组。

var colors=new Array(3);
var name=new Array("Grey");
  • 读取和设置数组时,要使用方括号并提供相应值基于0的数字索引;

var colors=["red","blue","green"];
alert(colors[0]); //显示第一项 red
colors[2]="black"; //修改第三项
colors[3]="brown"; //新增第四项
  • 数组的项数保存在length属性中,这个属性始终返回0或更大的数字。

  • 数组的length属性不只是只读的,通过设置这个属性可以从数组的末尾移除项或者向数组中添加新项。

//移除最后一项
var colors=["red","blue","green"];
colors.length=2; //移除数组的第三项
alert(colors[2]); //undefined
//在数组的末尾添加一项 undefined
var colors=["red","blue","green"];
colors.length=4;
alert(colors[3]); //undefined
//在数组的末尾添加两项 属性值
var colors=["red","blue","green"];
colors[colors.length]="black"; //(在位置3)添加一种颜色
colors[colors.length]="brown"; //(在位置4)添加一种颜色
  • 检测数组的两个方法;

    • instanceof 操作符,适用用单个网页或单个全局作用域

    • Array.isArray() 方法。适用用网页中包含多个框架,存在着两个及以上不同的全局作用域。

//instanceof
if(value instanceof Array){
//对数组执行某些操作
}
//Array.isArray()
if(Array.isArray(value)){
//对数组执行某些操作
}
  • 转换方法,所有对象都有toLocaleString()、toString()、和valueOf()方法。其中,调用valueOf()返回的是调用这个函数的变量本身,是数组类型的就返回这个数组的副本,是字符串返回的也是这个字符串的副本。toString()返回的是这个变量的字符串表示。而toLocaleString()就比较复杂,locale直译是地区的,通常情况下toLocaleString()返回的和toString()返回的相同,但对于Number、Date、Array而言会根据toLocaleString()的参数来返回不同格式的字符串。

var array1 = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];
var localeString = array1.toLocaleString('en', {
timeZone: "UTC"
});//可以cn表示中国的时间格式,en表示英国的时间格式
console.log(localeString);
// expected output: "1,a,12/21/1997, 2:12:00 PM",
// This assumes "en" locale and UTC timezone - your results may vary
  • 转换方法,还可以通过Array.join()来替代Array.toString().

var colors=["red","blue","green"];
colors.join(",");
colors.join("||");
  • 转换方法,如果数组中的某一项的值是null或者undefined,那么该值在 join()、toLocaleString()、toString()和valueOf()方法返回的结果中以空字符串表示。

  • 数组的常用方法:

    • push() 方法接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改过后的数组长度。

    • pop() 方法从数组末尾移除最后一项,减少数组的length值,并返回移除的项。

    • shift() 方法移除数组中的第一项并返回该项,同时将数组的长度减1。

    • unshift() 方法在数组的前端添加任意项,并返回新数组的长度。

    • reverse() 方法会反转数组项的顺序,并返回经过排序的数组。

    • sort() 方法按升序列排列数组,并返回经过排序后的数组,sort() 方法比较的是通过数组项的toString()转型方法得到的字符串,所以通常我们让sort() 接受一个比较函数来进行排序。

    • concat() 方法会先创建当前数组的一个副本,然后将接受的参数添加到这个副本的末尾,最后返回新构建的数组。

    • slice() 方法能够基于当前数组的一个或多个项创建一个新数组,一个参数的情况下slice() 方法返回从该参数指定的位置开始到数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项—但不包括结束位置的项。slice() 方法不会影响原始数组。

    • splice() 方法的主要用途是向数组的中部插入项,使用这种方法的方式有三种,删除、插入、替换。splice() 方法始终返回从原始数组中删除的项,如果没有删除任何向则返回一个空数组。

    • indexOf()和lastIndexOf() 方法都接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中indexOf() 方法从前向后找,lastIndexOf() 方法从后往前找。这两个方法返回的是要查找项的在数组中的位置,没有找到则返回 -1 。

  • 栈方法,栈是一种LIFO(Last-In-First-Out,后进先出)的数据结构,通过push()和pop() 方法可以模仿出栈的行为。

var colors=new Array();
var count=colors.push("red","green");
alert(count); // 2
count=colors.push("black");
alert(count); //3
var item=colors.pop();
alert(item); //black
alert(colors.length); //2
  • 队列,通过push() 和shift() 方法来模仿队列(先进先出)的行为。通过unshift()方法还可以从相反的方向来模仿队列。

//push()和shift()
var colors=new Array();
var count=colors.push("red","green");
alert(count);//2
count=colors.push("black");
alert(count);//3
var item=colors.shift();
alert(item); //red
alert(colors.length); //2
//push()和unshift()
var count=colors.unshift("red","green"); //red,green
alert(count); //2
count=colors.unshift("black"); //black,red,green
alert(count); //3
var item=colors.pop(); //green
alert(item)
alert(colors.length); //2
  • 排序,直接用来重新排序数组的方法有两个,reverse()方法是直接将数组反转项的顺序,sort()方法默认是通过每个数组项的toString()方法,然后比较得到的字符串,以确定如何排序,即便数组项是数字也是这样,大多数情况下得到的结果都不理想。通常情况我们会给sort()方法一个比较函数作为参数,来进行排序。

//比较函数
function comare(value1,value2){
if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
var values=[0,1,5,10,15];
values.sort(comare);
alert(values);
//修改比较函数的返回结果就可以得到降序
function comare(value1,value2){
if(value1 < value2){
return 1; //修改这里
}else if(value1 > value2){
return -1; //还有这里
}else{
return 0;
}
}
var values=[0,1,5,10,15];
values.sort(comare);
alert(values);
//对于数值或者valueOf方法会返回数值类型的对象类型,比较函数会更加简单
function comare(value1,value2){
return value2-value1;//这是降序
//return value1-value2; 这是升序
}
  • Array的迭代方法:
    ECMAScript5 为数组定义了五个迭代方法,每个方法都要接受两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象—影响this的值。传入这些迭代方法的函数都会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。

    • every() :对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。

    • filter() :对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。

    • forEach() : 对数组中的每一项运行给定函数,这个方法没有返回值。

    • map() :对数组中的每一项运行给定函数,返回每次函数调用结果组成的数组。

    • some() :对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。

    • 以上方法都不会修改数组中包含的值。

var numbers=[1,2,3,4,5,4,3,2,1];
var everyResult=numbers.every(function(item,index,array){
return (item>2);
});
alert(everyResult);
  • Array的归并方法:

    • reduce()

    • reduceRight()

    • 以上两个方法都是归并函数,一个从左到右另一个从右到左,这两个方法都接收两个参数:一个在每一项上调用的函数和(可选)作为归并的基础值。传给归并方法的函数接收4个函数:前一个值、当前值、项的索引和数组对象。

var values=[1,2,3,4,5];
var sum=values.reduce(function (prev,cur,index,array) {
return prev+cur;
},1);
alert(sum);//16

2019.11.29

红宝书阅读笔记ch4

红宝书阅读笔记ch4

基本类型和引用类型的值

  • 基本类型值指的是简单的数据段,而引用类型值可能是由多个值构成的对象。

  • 基本类型值是按值访问的,因为是可以操作再变量中实际的值,引用类型的值是保存内存中的对象,JavaScript不允许直接访问内存中的位置,在操作对象时,实际上是在操作对象的引用而不是实际的对象,因此,引用类型的值是按引用访问的。

  • 字符串是基本类型的,而不是引用类型的。

  • 对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。对于基本类型的值不能添加属性,尽管这样做不会导致任何错误。

  • 对于复制变量值,基本类型的值复制的是值,而引用类型复制的是这个值的指针,两个变量引用的是同一个对象,改变其中一个的值,就会影响另一个值。

  • ECMAScript中所有的函数的参数都是按值传递的。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,则如同引用类型变量的复制一样。对于访问变量有按值和引用两种方式,而参数只能按值传递,这一点可以归功于函数的执行环境和作用域。

  • typeOf 操作符用于检测基本数据类型,而instanceof 操作符可以检测某个值是不是对象,是什么类型的对象。

执行环境和作用域

  • 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。全局执行环境是最外围的一个执行环境,在Web浏览器中,全局执行环境被认为是Window对象。

  • 作用域链,是代码在一个环境中执行时为变量对象创建的,作用是保证对执行环境有权访问的所有变量和函数的有序访问,即里层的执行环境可以访问外部执行环境的变量和函数,而外部的执行环境无权访问里层的执行环境。全局执行环境是作用域链的最后一个对象。当前环境是作用域的前端。

  • 函数参数也被当做变量对待,访问规则和执行环境中的其他变量相同(即arguments数组)。

  • 延长作用域链的方法有两个:

    • try-catch语句的catch块;

    • with语句。

  • 上述的两个语句都会在作用域的前端添加一个变量对象。对with语句来说,会将指定对象添加到作用域中。对catch语句来说,会创建一个新的变量对象,其中包含的是抛出的错误对象的声明。

  • JavaScript 没有块即作用域,在其他类C的语言中,有花括号封闭的的代码都有自己的作用域。(如if、for等语句)在这些有花括号的语句中创建的变量会在语句结束后添加到当前的执行环境中,如for循环中创建的i 会在循环结束后添加到当前的执行环境中,这一点需要注意。

  • 使用var声明的变量会自动被添加到最近的环境中。在函数内部,最接近的环境就是函数的局部环境;在with语句中,最接近的环境是函数环境。如果初始化变量时没有使用var声明,该变量会被添加到全局环境中。

  • 标识符,就是声明变量的变量名,在某个环境中为了读取或写入而引用一个标识符是,必须通过逐级搜索标识符才能确定标识符实际代表什么,如果在局部环境中没有找到该变量名则继续沿用作用链向上搜索,知道全局环境,如果在全局环境中就证明没有申声明这个该变量。如果在某个局部环境中找到了,就不继续向上搜索了。也可以认为在局部环境中存在着同名的标识符,就不会使用父环境中的标识符。

垃圾收集

  • 垃圾收集有两种方式,标识清除和引用记数两种方式,现常用的是标识清除。

红宝书阅读笔记ch3-3

红宝书阅读笔记ch3-3

语句

由于笔者对if、do-while、while、for、break、continue、switch这些语句已经很熟悉了,这里就不在这里花跟更多的功夫去记了,如果有不了解这些流程控制语句的读者可前往:w3schoo菜鸟教程网 了解相应的语句。
接下来笔者会记一下以往不熟悉的语句,如label、with等。

  • for-in语句,是一种精准的迭代语句,可以用来枚举对象的属性。
    语法:
    for (property in expression) statement
    示例:

for (var proName in window) {
document.writeln(proName);
}

注意:由于ECMAScript对象的属性没有顺序,因此对于for-in语句循环输出的语句是不可预测的,虽然每个属性都会返回一次,但返回的先后顺序因浏览器而异。如果迭代对象的变量值为null或undefined,for-in语句会抛出错误,在 ES5以后,对于这种情况不再抛出错误而是不再执行循环体。为了保证兼容性,建议在使用for-in语句以前,先检测该对象的值是不是null或undefined。

  • 使用label语句可以在代码中添加标签,以便将来使用。
    语法:
    label: statement
    举例:

var num=0;
outermost:
for(var i=0; i<10;i++){
for(var j=0; j<10; j++){
if(i==5 && j==5){
break outermost;
}
num++;
}
}
console.log(num); //55
var num=0;
outermost:
for(var i=0; i<10;i++){
for(var j=0; j<10; j++){
if(i==5 && j==5){
continue outermost;
}
num++;
}
}
console.log(num); //95

标签由break或continue语句引用。加标签的语句一般都是要与for语句等循环语句使用。

  • with语句的作用是将代码的作用域设置到一个特定的对象中。
    语法:
    with (expression) statement ;
    定义with语句的主要目的是为了简化编写多次编写同一个对象的工作,举例:

var qs=location.search.substring(1);
var hostName=location.hostname;
var url=location.href;
//上面的代码都包含location对象,使用with语句改写如下:
with (location){
var qs=search.substring();
var hostName=hostname;
var url=href;
}

注意:大量使用with语句会导致性能下降,同时也给代码调试带来不便,因此在开发大型应用程序时,不建议使用with语句。同时严格模式下不允许使用with语句。

函数

  1. 通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。

  2. 要么让函数始终都返回一个值,要么永远都不要返回值。

  3. ECMAScript中参数在内部是用一个数组来表示,在函数体内通过arguments对象来访问这个参数数组,从而获取传给函数的每一个参数。

function sayHi(){
alert("Hello "+arguments[0]+","+arguments[1]);
alert(arguments.length); //参数数组的长度
}
function doAdd(){
if(arguments.length==1){
alert(arguments[0]+10);
}else if(arguments.length==2){
alert(arguments[0]+arguments[1]);
}
}
doAdd(10); //20
doAdd(10,30); //40
//arguments对象可以和命名参数一起使用
function doAdd(num1,num2){
if(arguments.length==1){
alert(arguments[0]+10);
}else if(arguments.length==2){
alert(num1+arguments[1]);
}
}
doAdd(10);
doAdd(10,30);
  1. ECMAScript因为没有函数签名所以做不到真正的重载,如果在ECMAScript定义了两个名字相同的函数,则改名字属于后定义的函数。

  2. 通过检查传入函数中参数的类型和数量并做出不同的反应可以模仿方法的重载。

freeCodeCamp 前端开发课程 220(Profile Lookup)

freeCodeCamp 前端开发课程 220(Profile Lookup)

今天在FCC上遇到了一题较难的题目记录下来,以备后用。

题目:
我们有一个对象数组,里面存储着通讯录。

函数 lookUp 有两个预定义参数:firstName值和prop属性 。

函数将会检查通讯录中是否存在一个与传入的 firstName 相同的联系人。如果存在,那么还需要检查对应的联系人中是否存在 prop属性。

如果它们都存在,函数返回prop属性对应的值。

如果firstName 值不存在,返回 “No such contact”。

如果prop 属性不存在,返回 “No such property”。


源码:

//初始化变量
var contacts = [
{
"firstName": "Akira",
"lastName": "Laine",
"number": "0543236543",
"likes": ["Pizza", "Coding", "Brownie Points"]
},
{
"firstName": "Harry",
"lastName": "Potter",
"number": "0994372684",
"likes": ["Hogwarts", "Magic", "Hagrid"]
},
{
"firstName": "Sherlock",
"lastName": "Holmes",
"number": "0487345643",
"likes": ["Intriguing Cases", "Violin"]
},
{
"firstName": "Kristian",
"lastName": "Vos",
"number": "unknown",
"likes": ["Javascript", "Gaming", "Foxes"]
}
];
function lookUp(firstName, prop){
// 请把你的代码写在这条注释以下
// 请把你的代码写在这条注释以上
}
// 你可以修改这一行来测试你的代码
lookUp("Akira", "likes");

解法一:

function lookUp(firstName, prop){
// 请把你的代码写在这条注释以下
var hasName = false,hasprop = false,propValue;
for (var i=0,len=contacts.length; i<len; i++){
if (hasName && hasprop) break;
for (var key in contacts[i]) {
if (contacts[i].firstName == firstName) {
hasName = true;
if (key == prop) {
hasprop = true;
propValue = contacts[i][key];
} else {
continue;
}
break;
}
}
}
if (hasName) {
if (hasprop) {
return propValue;
} else {
return "No such property";
}
} else {
return "No such contact";
}
// 请把你的代码写在这条注释以上
}

最优解法:

function lookUp(firstName, prop) {
for(var i = 0; i < contacts.length; i++) {
if(contacts[i].firstName === firstName) {
return contacts[i][prop] || "No such property"
}
}
return "No such contact"
}

我的解法:
btw 我的解法在.hasOwnProperty 不行,记录下来下次再看看。

function lookUp(firstName, prop){
// 请把你的代码写在这条注释以下
for(i=0; i<contacts,length; i++){
if(contacts[i].firstName === firstName){
if(contacts[i].hasOwnProperty(prop)){
return contacts[i][prop];
}
}
return "No such contact";
}
// 请把你的代码写在这条注释以上
}
红宝书阅读笔记ch3-2

红宝书阅读笔记ch3-2

操作符

操作符用于操作数据值,包括算术操作符、位操作符、关系操作符和相等操作符。
ECMAScript操作符适用于很多值,例如字符串、数字值、布尔值,甚至对象。

一元操作符

  • 递增和递减操作符

    • 递增和递减操作符,有前置型和后置型。

    • 执行前置型递增和递减操作时,变量的值都是在语句求值以前改变的。

    • 后置型递增和递减操作是在它们的语句被求值之后才执行的。

  • 一元加和减操作符

    • 一元加操作符以一个加号(+)表示,可用以加对非数值进行转换。

    • 一元减操作符以一个加号(-)表示,同样也可以用于对非数值的转换,然后再将数值转换为负数。

  • 位操作符,简单点说就操作二进制的运算。

    • 按位非(NOT),由一个波浪线(~)表示,返回二进制数值的反码。

    • 按位与(AND),由一个和号字符(&)表示,它有两个操作数,将两个数值的每一位对齐,1 0 得0,0 1得0,1 1得1。

    • 按位或(OR),由一个竖线符号(|)表示,同样也有两个操作数,在两个位有一个位是1就返回1,而只有两个0才返回0。

    • 按位异或(XOR),由一个插入符号(^)表示,也有两个操作数,1 1得0,1 0得1,0 1得1,0 0得0。

    • 左移操作符由两个小于符号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数,左移会以0来填充空位。

    • 有符号的右移操作符由两个大于号(>>)表示,将数值向右移动,但保留符号位。

    • 无符号右移操作符由3个大于号(>>>)表示,这个操作符会将所有的32位都向右移动,对于正数来说有符号右移和无符号右移相同,但是对于负数来说无符号右移会把负数的二进制码当成正数的二进制码,而且负数以其绝对值的二进制补码形式表示,会导致无符号右移后结果会非常大。

布尔操作符

布尔操作符有三个:NOT、AND、OR。

  • 逻辑非操作符由一个叹号(!)表示,可以应用于所有数据类型。无论这个值是什么类型,这个操作符都会返回一个布尔值。逻辑非会先将值转换为布尔值,再将其求反。

    • 转换规则:

    • 如果操作数是一个对象,返回false;

    • 如果操作数是一个空字符串,返回true;

    • 如果操作数是一个非空字符串,返回false;

    • 如果操作数是数值0,返回true;

    • 如果操作数是任意非0数值(包括Infinity),返回false;

    • 如果操作数是null,返回true;

    • 如果操作数是Nan,返回true;

    • 如果操作数是undefined,返回true。

alert(!false); //返回true
alert(!"blue"; //返回false
alert(!0); //返回true
  • 逻辑与操作符由两个和号(&&)表示,有两个操作数,真真为真,真假为假,假真为假,假假为假,可应用于所有类型的操作数。

    • 在有一个操作数不是布尔值的情况下,逻辑与就不一定返回布尔值;此时它遵循以下规则:

    • 如果第一个操作数是对象,则返回第二个数;

    • 如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象;

    • 如果两个操作数都是对象,则返回第二个操作数;

    • 如果第一个操作数是null,则返回null;

    • 如果第一个操作数是NaN,则返回NaN;

    • 如果第一个操作数是undefined,则返回undefined;

    • 逻辑与操作属于短路操作,即第一个是为false,那么就不会判断第二个是真还是假的了,它会直接返回false,而不会判断第二个操作数。

  • 逻辑或操作符由两个竖线符号(||)表示,有两个操作数,真真为真,真假为真,假真为真,假假为假。

    • 如果有一个操作数不是布尔值,逻辑或不一定返回布尔值,遵循规则如下:

    • 如果第一个操作数是对象,则返回第一个操作数;

    • 如果第一个操作数的求值结果为false,则返回第二个操作数;

    • 如果两个操作数都是对象,则返回第一个操作数;

    • 如果两个操作数是null,则返回null;

    • 如果两个操作数是NaN,则返回NaN;

    • 如果两个操作数是undefined,则返回undefined。

    • 逻辑或同样也是短路操作,如果一个操作数的值为true,那么就不会判断第二个操作数的值了。通过这一点我们可以用来避免给变量赋值为null或undefined值。

var myObject = preferredObject || backupObject;

乘性操作符

  • ECMAScript定义了三个乘性操作符,乘法(*)、除法(/)和求模(%),与其他语言用途类型,只是操作数为非数值的情况下会执行自动类型转换,也就是空字符串将被当做0,布尔值true会被当做0。

  • 其他类型的转换规自行看书,P47。

加性操作符

在ECMAScript中加和减除了简单的算术运算外还有一系列的特殊操作。

  • 加法,用(+)表示

    • 如果操作数两个都是数值,执行常规的加法计算;

    • 如果是NaN、Infinity、-Infinity那么返回的结果也是这三种数据类型。

    • 如果+0、-0那么返回的还是0。

    • 如果有两个操作数都是字符串,则将第二个操作数和第一个操作数拼接起来。

    • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接起来。

    • 如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串,然后再应用前面关于字符串的规则。对于null和undefined,则分别调用函数String()取得字符串”null”和”undefined”。

  • 减法操作符,(-)

    • 如果两个操作数都是数值,则执行常规的算术减法并返回结果。

    • 正无穷减正无穷的结果是NaN,负无穷减负无穷的结果是负无穷。

    • 零减零的结果是零。

    • 如果有一个操作数是字符串、布尔值、null、或undefined,则先在后台调用Number()函数将其转换为数值,然后在根据前面的规则执行减法运算。如转换的是NaN,则减法的结果就是NaN。

    • 如果有一个操作数是对象的话,则调用对象的valueOf()方法取得表示该对象的数值。如果得到的是NaN,则减法的结果就是NaN。如果对象没有valueOf()方法,则调用其的toString()方法并将得到字符串转换为数值。

关系操作符

小于(<)、大于(>)、小于等于(<=)和大于等于(>=)这几个关系操作符用于对两个值的比较,并返回一个布尔值。

  • 如何两个操作数都是数值,则执行数值比较。

  • 如果两个都是字符串,则比较两个字符串对应的字符编码值。

  • 如果有一个操作数是数值,则将另一个操作数转换为数值再执行数值比较。

  • 如果有一个操作数是对象,则先调用这个对象的valueOf()方法,用得到的结果按照前面的规则进行比较,如没有valueOf()方法,则调用toString()方法,并用得到的结果根据前面的规则执行比较。

相等操作符

相等不相等-–先转换再比较
全等不全等—仅比较不转换

  • 相等操作符由两个等号(==)表示,如果两个操作数相等,则返回true。而不相等操作符由叹号后跟等号(!=)表示,如果两个操作数不相等,则返回true。这两个操作符都会先转换操作数(俗称强制转型),然后再比较它们的相等性。

    • 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值—false转换为0,而true转换为1;

    • 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先把字符串转换为数值;

    • 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型按照前面的规则进行比较;

    • null和undefined是相等的;

    • 要比较相等性之前,不能将null和undefined转换成其他任何值。

    • NaN和任何类型的值都不相等,包括它自己。

    • 如果两个操作数都是对象,则比较它们是不是同一个对象。

  • 全等和不全等
    全等和不全等,除了不转换操作数之外,其比较规则与相等和不相等一样。

    • 全等操作符由三个等号(===)表示。

    • 不全等操作符由一个叹号和三个等号(!===)表示。

    • 需要注意的一点null和undefined是相等的,但不是全等的,因为它们不是一个类型。

条件操作符

ECMAScript的条件操作符与Java的条件操作符语法相同。

var variable = boolean_expression ? true_value : false_value;

赋值操作符

简单的赋值操作符由等于号(=)表示,其作用就是把右侧的值赋给左侧的变量。除此之外还可以在等于号前面添加 加减乘除、取模操作符或位操作符完成复合操作。

var num=10;
num +=10; //等同于num = num +10

逗号操作符

逗号操作符多用于声明多个变量;除此之外逗号操作符还可以用于赋值。在用于赋值时,逗号操作符总会返回表达式的最后一项。

var num1=1,num2=2,num3=3;
var num = (5,4,1,8,0); //num的值为0
红宝书阅读笔记ch3-1

红宝书阅读笔记ch3-1

基本概念-ECMAScript基础语法
语法、关键字和保留字、 变量、 数据类型

语法

  1. 区分大小写,ECMAScript中的一切都区分大小写。

  2. 标识符,就是指变量、函数、属性的名字,标识符有以下几个规则:

    • 第一个字符必须是一个字母、下划线(_)、或一个美元符号;

    • 其他字符可以是字母、下划线、美元符号或数字;

    • ECMAScript标识符采用驼峰大小格式,也就是第一个字母小写,剩下的每个单词的首字母大写,例如:firstSecond、myCar、doSomethingImportant。

    • 不能把关键字、保留字、true、false和null用作标识符。

    • 可以包含扩展的ASCII或Unicode字母字符。但是不建议这样做,因为很容易和英文混淆。

  3. 注释
    //单行注释
    /* 这是一个多行注释 */

  4. 严格模式
    使用 “use strict” 指令
    “use strict” 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。
    它不是一条语句,但是是一个字面量表达式,在 JavaScript 旧版本中会被忽略。
    “use strict” 的目的是指定代码在严格条件下执行。
    严格模式下你不能使用未声明的变量。
    Note 支持严格模式的浏览器:
    Internet Explorer 10 +、 Firefox 4+ Chrome 13+、 Safari 5.1+、 Opera 12+。
    为什么使用严格模式:
    -消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

    • 消除代码运行的一些不安全之处,保证代码运行的安全;

    • 提高编译器效率,增加运行速度;

    • 为未来新版本的JavaScript做好铺垫。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>使用 "use strict":</h1>
<h3>不允许使用未定义的变量。</h3>
<p>浏览器按下 F12 开启调试模式,查看报错信息。</p>
<script>
"use strict";
x = 3.14; // 报错 (x 未定义)
</script>
</body>
</html>
  1. 语句

    • ECMAScript中的语句以一个分号结尾;如果省略分号,则由解析器确定语句的结尾。

    • 在控制语句中使用代码块可以让编程意图更加清晰。


关键字和保留字

  • 关键字用于表示控制语句的开始和结束或者执行特定的规则。

  • 关键字不能用在标识符。

break do instanceof typeof
case else new var
catch finally return void
continue for switch while
debugger function this with
default if throw
delete in try
  • 保留字是一组不能用作标识符的字符,尽管现在这些保留字在这门语言中没有特定的用途但将来可能会用作关键字。

abstract enum int short
boolean export interface static
byte extends long super

变量

  • ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任意类型的数据。

  • 定义变量时要使用var操作符,后跟一个变量名,如下所示:
    var message;
    这行代码定义了一个名为message的变量,该变量可以用来保存任何值,像这样未经过初始化的变量,会保存一个特殊的值—undefined。

  • ECMAScript也支持直接初始化变量,因此在定义变量的同时就可以设置变量的值,如下所示:
    var message = “hi”;

  • 在变量message中保存一个字符串值”hi”。像这样初始变量并不会把它标识为字符串类型;初始化的过程就是给变量赋一个值那么简单。因此,可以在修改变量值的同时修改值的类型,如下所示:
    var message = “hi”;
    message = 100; //有效,但不推荐

  • 如果在函数中使用var定义一个变量 ,那么这个变量在函数退出后就会被销毁。

  • 在函数中省略var操作符定义的变量,只要调用了一次该函数,该变量就会变成全局变量,但是这样的方法不被推荐,因为在局部作用域中定义的全局变量很难维护。

  • 可以使用一条语句定义多个变量,只要把每个变量用逗号分隔开即可;
    var message=”hi”;
    found=false;
    age=29;

  • 在严格模式下,不能定义名为eval或arguments的变量,否则会导致语法错误。


数据类型

  • ECMAScript中有五种基本数据类型:Undefined、Null、Boolean、Number和String。

  • 还有一种复杂数据类型—Object,Object本质上是一组无序的名值对组成。

    1. typeof操作符
      typeof操作符是用来检测给定变量的数据类型,对一个值使用typeof可能返回下列某个字符串:

      “undefined”—如果这个值未定义;
      “boolean”—如果这个值是布尔值;
      “string”—如果这个值是字符串;
      “number”—如果这个值是数值;
      “object”—如果这个值是对象或者是null;
      “function”—如果这个值是函数。
var message="some string";
alert(typeof message); //"String"
alert( (typeof message) ); //"String"
alert(typeof 95); //"String"

注意

1.调用typeof null会返回”object“,因为特殊值null被认为是一个空的对象引用。
2.Safari 5及之前的版本、Chrome 7 及之前版本在对正则表达式调用typeof操作符时会返回”function”,而其他浏览器在这种情况下会返回”object”。
3.从技术角度上来说,函数在ECMAScript中是对象,而不是一种数据类型。然而,函数也确实有些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的。

  1. undefined类型

    • Undefined类型只有一个值,即特殊的undefined。

    • 在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。

    • 声明变量的值为undefined,与声明变量未初始化的值,相等。

    • 包含undefined值的变量与尚未定义的变量还是有不同的。

var message;
alert(message==undefined); //true
var message=undefined;
alert(message==undefined); //true
  1. Null类型

    • Null类型是第二个只有一个值的数据类型,这个特殊的值是null。

    • 从逻辑的角度来看,null值表示一个空对象指针,这也是typeof操作符检测null值会返回”object”的原因。

    • 如果定义的变量准备在将来保存一个对象,那么最好将该变量初始化为null而不是其他值。这样一来,只要检查null的值就可以知道相应的变量是否已经保存了一个的对象的引用。

    • undefined值派生自null值,因此ECMA-262规定对它们的相等性测试要返回true。

    • 不要将一个对象的值显式的设置为undefined。

    • 只要在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存null值。这样不仅可以体现null作为空对象指针的惯例,还能进一步区分null和undefined。

  2. Boolean 类型

    • Boolean 类型只有两个字面值:true和false。

    • Boolean 类型的字面值区分大小写,

    • ECMAScript中所有的值都有与这两个Boolean值等价的值。要将一个值装换为对应的Boolean值,可以调用转型函数Boolean()。

    • 控制语句能将其他的数据类型转换成Boolean类型。

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 “” (空字符串)
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined n/a undefined
var message="Hello world";
if(message){
alert("Value is true");
}
  1. Number 类型

    • 浮点数值
    • Number 类型用来表示整数和浮点数值。

    • 支持不同的数值字面值格式包括十进制整数、十六进制整数、八进制整数。

    • 八进制字面值第一位必须是零(0),然后八进制数字序列(0~7)。如果字面数值超出了范围,那么前导零将被忽略,后面的数值当做十进制解析。

    • 八进制字面值在严格模式下是无效的,会导致支持该模式的JavaScript引擎抛出错误。

    • 十六进制字面值前面两位是0x,后跟任何十六进制数字(0~9即A~F)。其中A~F可以大写也可以小写。

    • 浮点数值,就是该数值必须包括一个小数点,并且小数点后面必须至少有一位数字。小数点前面可以没有整数。

    • ECMAScript会选择性的将浮点数值转换成整数。

    • 对于那些极大或极小的数值,可以用科学计数法。

    • 浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。例如0.1加上0.2的结果不是0.3,而是0.30000000000000004。

    • 数值范围
    • 数值范围,ECMAScript能够表示的最小数值保存在 Number.MIN_VALUE,这个值是5e-324,能够表示最大数值保存在Number.MAX_VALUE,这个值是1.7976931348623157e+308。

    • 如果某次计算得到了超出JavaScript数值范围的值,那么这个数值将被自动转换为特殊的Infinity值。正数是正无穷,负数是负无穷。Infinity不能参与计算。

    • 想要确定某个数值是否超过数值范围,可以使用isFinite()函数,这个函数在参数位于最小和最大数值之间会返回true。

    • NaN
    • NaN,即非数值(Not a Number),是一个特殊的值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况,这样就不会报错了。

    • NaN本身有两个特点,首先任何涉及到NaN的操作都会返回NaN。其次,NaN与任何值都不相等包括它自己。

    • isNaN()函数用于确定参数是否“不是数值”。 isNaN()函数在接收到一个参数后,会尝试将这个值转换为数值。某些不是数值的值会直接转换成数值,例如字符串”10”或Boolean值。而任何不能转换为数值的值都会导致这个函数返回true。

    • 数值转换
    • 将非数值转换为数值的方法有三个,分别是Number()、parseInt()和parseFloat()。

  2. String类型

    • 在ECMAScript字符串的表达方式可以是双引号也可以是单引号,只是用单引号开始也必须用单引号结束,双引号同理。

    • 字符字面量==转义字符,也就是反斜杠。

    • ECMAScript的字符串不可变,要改变某个变量保存的字符串,就要销毁原来的字符串,再用一个包含新值的字符串来填充该变量。

    • 将一个值转换为String 的方法有两个,toString()和String()。

    • 除了null和undefined类型外,其他的类型都有toString()方法。

  3. Object类型

    • ECMAScript中的对象其实就是一组数据和功能的集合。

    • Object 类型是所有它的实例的基础。