JavaScript随笔记(一)基础概念以及变量类型 一.JavaScript中的基础概念 数据类型 操作符需要注意的地方

1.defer属性

一般我们在引用外部js文件的时候往往是将引用文件的位置放在标签当中,比如那么在标签中引入多个js文件时,浏览器会按照引入顺序加载执行这些引入的js文件,如果加载执行的这些js文件的时间比较长,那么页面就会处在等待期间。在下载引入的js文件时,现在的浏览器大多都是会并行下载的,不会去单线程的下载,这样提高了效率,但仍然会阻塞一些其他资源的下载比如说图片的下载,这样就因为js的下载执行而阻塞了UI渲染,会在页面上形成空白页面,这时我们可以有多种办法解决这个问题。比如说使用defer属性,虽然使用defer属性这不是最好的办法

脚本会被延迟到整个HTML页面都解析完毕后再运行,HTML5规范要求脚本按照出现的先后顺序执行,因此,第一个延迟脚本会在第二个延迟脚本之前执行。但是事实中并不一定是这样的,所以建议页面中只包含一个延迟脚本。并且这个defer属性只适用于外部脚本文件(引入脚本文件 src = "...")

2.作用域

  • 全局作用域

在函数外部声明的或者定义的变量属于全局作用域的范围,事实上在函数外部声明或者定义的变量会被作为window对象的属性。
示例代码如下:

var msg;//声明一个变量会作为window对象的属性
alert(msg);//输出undefined
  • 局部作用域
    在函数中使用var操作符定义的变量为局部变量 函数退出后这个变量就会销毁,看看下面的代码:
function test(){
   var msg = "hi";//在函数中定义一个变量,当函数执行完成后 这个变量就会销毁
}
test();//调用test函数,函数执行完成后,变量msg就会销毁
alert(msg + "_debug");//解析错误

但是需要注意的是,声明或者定义变量时省略var操作符会直接定义全局变量,如下所示:

function test(){
    msg = "hi";//直接定义全局变量
}
test();
alert(msg + " -sss");//   输出hi -sss

数据类型

JavaScript这门语言属于数据松散类型的语言,但是也有5种基本数据类型:Undefined,Null,Boolean,Number,和String和一种复杂数据类型(引用类型)Object,可以使用typeof操作符检测给定变量的类型。

  • Undefined类型

Undefined类型只有一个值,也就是undefined.在使用var关键声明一个变量而未对其进行初始化时,这个变量的值就是Undefined。但是需要注意的是:只声明没有初始化的变量的值是undefined, 但是如果没有声明变量而直接使用一个没有声明的变量会报错看看下面的代码呗

var msg;//这个变量声明之后虽然没有初始化但是获得了undefined值
alert(msg);//输出undefined
alert(msg == undefined);//输出true
alert(aa);//aa并没有声明 报错 ReferenceError: aa is not defined

然而,恶心的地方是在于使用typeof操作符判断一个无论是否进行过声明的变量都会返回undefined,如下所示:

var msg;//这个变量声明之后虽然没有初始化但是获得了undefined值
//age并没有声明
alert(typeof msg);//输出undefined
alert(typeof age);//age并没有声明 但是依然会返回undefined
  • Null类型

Null类型也是只有一个值的特殊数据类型,即null,null表示一个空对象指针 而用typeof检测null值会返回object,如果要声明一个变量指向一个对象(Object),那么可以声明时先var dog = null; 如下所示:

var dog = null;
alert(dog);//输出空白
alert(typeof dog);//输出object

实际上,undefined值是派生自Null值的,所以他们的相等性测试会返回true alert(undefined == null);//输出true.尽管,undefined和null有着这样的关系,但是他们的用途是完全不同的,声明一个对象时,尽量让这个指向对象的变量指向null,即体现了null作为空对象指针的惯例,又有助于区分undefined和null.

  • Boolean类型

Boolean类型的值只有true和false,但是任何类型的值调用Boolean()函数,都可以返回一个Boolean类型的值,看看下面的代码示例:

String 类型,如果是非空的字符串 转换完成后是true 如果是空字符串是false

var msg = "hi" ;
var msg1 = "";
alert(Boolean(msg));//  非空字符串 输出true
alert(Boolean(msg1)); // 空字符串 输出false

Number类型,如果是非零的数值则会转换为true,如果是0或者NaN则会转换为false

alert(Boolean(0));//输出false
alert(Boolean(222));//输出true

Obeject类型,如果是Object类型的变量并且指向一个对象,那么返回true,如果指向的是null,那么返回false.看看下面的代码:

var t1 = new Object();
console.debug(Boolean(t1));//true
var t2;
console.debug(Boolean(t2));//false
var t3 = null;
console.debug(Boolean(t3));//false
function isNull(obj){
    if(obj){
        console.debug('obj不为空');
    }else{
        console.debug('obj为空');
    }
}
isNull(t1);//obj不为空
isNull(t2);//obj为空
isNull(t3);//obj为空
  • Number类型

1.浮点数值

由于保存浮点数值所需要的内存空间是保存整数值的两倍,因此ECMAScript会尽量的将float可以转化整数值
如果一个小数点后面没有数字,那么这个数值就会作为整数存储,如果浮点数本身就是一个整数,比如1.0也会转换为整数
存储。如下所示:

var n1 = 1.0;//虽然是浮点数,但是等于一个整数,解析为1
var n2  = 2.;//小数点后没有数字,解析为2

2.NaN值

NaN值(Not a Number 非数值型)表示本来要返回数值的操作结果却未返回数值的情况。比如 1/0这样的操作
NaN有两个特点::
1任何涉及NaN的操作(例如NaN/10)都会返回NaN
2.NaN与任何数值包括NaN都不想等 比如NaN == NaN 返回false
isNaN()函数可以帮助我们确定这个参数 是否为不是数值 比如 isNaN(NaN);返回true

3.数值转换
数值转换时使用的转换函数:Number()、parseInt()、parseFloat()
1.Number()函数的转换规则:适用于任何数据类型。

  • boolean值 true和false分别被转换为 1 和 0;

  • 数值只是简单的传入和返回;

  • null转换为 0;

  • undefined转换为 NaN;

  • 目标是字符串时的转换规则:
    字符串中只包含数字,将其转换为十进制数值,前导0会被忽略(包括了八进制的转换,因为八进制是有前导0和其他0-7的数字组成);字符串中包含有效浮点值,转换为对应的浮点数;字符串中包含有效的十六进制数,会转换为相等的十进制数值(比如“0xf”);空字符串转换为0;

  • 目标是对象的转换规则:
    如果目标是对象,则调用对象的valueOf()方法,然后按照前面的规则转换返回值,如果转换的结果是NaN,则调用对象的toString()方法,
    然后再次按照前面的规则转换返回的字符串值.可以看看下面的示例代码:

var num1 = Number("Hello world!");  //NaN
var num2 = Number("");              //0
var num3 = Number("000011");        //11
var num4 = Number(true);            //1

2、parseInt()转换函数

parseInt(parseNum,radix)函数,第一参数为需要转换的数值,第二个参数为基数,即以radix为基数,
对parseNum进行转换,转换完成后返回的数值是10进制数,并且为number类型,这种转换方法主要是用来转换字符串,
parseInt会会略字符串前面的空格字符得到结果的第一个字符不是数字字符和负号(-),将返回NaN。
parseInt()可以接受两个参数,第一个值表示要进行转换的值,第二个表示转换的方式(十进制、十六进制、或者八进制格式)。
当没有第二个参数时,默认转换为十进制。

        var num1 = parseInt("11", 2);         //3  parsed as binary
        alert(typeof(num1));                        // alert number 为number类型
        var num2 = parseInt("15", 8);         //13 parsed as octal
        var num3 = parseInt("10", 10);        //10 parsed as decimal
        var num4 = parseInt("11", 16);        //17 parsed as hexadecimal

3、parseFloat()转换方法,该方法会始终忽略前导0且只有一个小数点有效,如果小数点之后只有数字0,将会返回整数。

4、其他的转换方法
toFixed()自动四舍五入,接受一个参数,表示返回值的小数位数。
toExponential()以指数表示法返回字符串。
toPrecision(),自动选择合适的表示方法。

注:这三个方法都会返回字符串。

   var num3 = parseFloat("10.12345", 10);
   alert(typeof num3);//转换完成后为number类型
   var num3Str = num3.toFixed(4);//四舍五入后返回的是string类型
   alert(num3Str);//10.1235
   alert(typeof num3Str);//string类型

操作符需要注意的地方

  1. 对于 + 操作符,如果有一个操作数是字符串类型,那么另一个操作数会转换为字符串,然后拼接起来,看看下面的代码
var f = true;
alert(f);//true
alert(typeof f);//boolean
var s = "";
alert( s + f);//输出true
var fs = s+f;
alert( typeof fs);//返回String
var str = 'test_';
var strT = str + f;
alert(strT);//test_true
alert(typeof strT);//string
var num = 5;
var s = "5";
var ss = num+s;
alert(ss);//输出55  将num转换为字符串的5 然后与5拼接得 字符串55
alert(typeof ss); //string
var is = parseInt(s);
alert(is + num);//输出10

2.比较操作符 > < <= =>

  • 如果两个操作数都是数值 ,进行数值比较,
  • 都是字符串,则比较两个字符串的字符编码值
  • 只有一个操作数是数值,则将另一个操作数转为数值进行比较
  • 如果有一个操作数是布尔值,则先将其转换为数值,然后再进行比较。
  • 如果一个操作数是对象,则调用这个对象的valueOf()方法,用前面的规则。如果对象没有valueOf()方法,则调用toString()方法
  • 如果两个操作数都是对象,则比较他们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作返回true,否则返回false
    null和undefined是相等的
// == 与 != 的判断是先转换再判断
var result =  "1" == 1;//  字符串会转换为数值 true
result =   "1" == 0;//  字符串会转换为数值 false
result = null == undefined;//null 与undefined 相等
result = null ==NaN;//NaN无论跟什么比较 都不相等false
result = NaN == NaN;//NaN即使与NaN比较 都是false
//若是比较两个对象是否==  则是是否指向同一个对象
var o1 = new Object();
var o2 = new Object();
var o3 = o1;
alert('o1==o2 ? ' + (o1==o2));//false
alert('o1==o3 ? ' + (o1==o3));//true