基础一

词法结构

  1. JavaScript程序是用Unicode字符集编写的
  1. JavaScript是区分大小写的, 而HTML不区分大小写.
  2. JavaScript会忽略程序中标识之间的空格.
  3. JavaScript支持"//"和"/.../"两种注释.
  4. 直接量: 程序中直接使用的数据值. JavaScript中的直接量为: 数值, 字符串, 布尔型和正则表达式.
  5. JavaScript的标识符必须以字母, 下划线或者美元符号开始, 后续跟字母, 数字, 下划线或者美元符号.
  6. JavaScript中关于填补分号的规则: 只要在缺少了分号就无法正确解析代码的时候, JavaScript才会填补分号.

类型, 值和变量

概述
  1. JavaScript的数据类型分为两类: 原始类型和对象类型. JavaScript的原始类型包括数字, 字符串和布尔值. 而对象是属性的集合, 每个属性都由"名/值对"组成.
  2. JavaScript中有两个特殊的原始值:** null和undefined**, 它们不是数字,字符串和布尔值. 它们通常分别代表了各自特殊类型的唯一的成员. 原始类型, null和undefined均为不可变类型.
  3. 普通的JavaScript对象是"命名值"的无序集合, 可以使用Object.keys()获取其keys(新版本可以使用Object.values()获取其values). 而JavaScript定义了一种有序集合, 为数组.
var o={
            name:'张三',
            sex:'男',
            sayHello:function(){
                conosle.log("sayHello");
            }
        };
        console.log(Object.keys(o));
        console.log(Object.values(o));

结果:
Array [ "name", "sex", "sayHello" ]
Array [ "张三", "男", o.sayHello() ]

  1. JavaScript定义了另一种特殊对象--函数. 函数是具有与它相关联的可执行代码的对象, 通过调用函数来运行可执行代码, 并返回运算结果.
  2. 如果函数用来初始化(使用new运算符)一个新建的对象, 我们称之为构造函数. 每个构造函数定义了一类对象--由构造函数初始化的对象组成. 类可以看做是对象类型的子类型. 除了数组类和函数类之外, JavaScript语言核心还定义了三种有用的类: 日期(Date)类定义了代表日期的对象. 正则(RegExp)类定义了表示正则表达式的对象. 错误(Error)类定义了那些表示JavaScript程序中运行时错误和语法错误的对象.
  3. JavaScript解释器有自己的内存管理机制, 可以自动对内存进行垃圾回收.
  4. JavaScript变量是无类型的, 变量可以被赋予任何类型的值. 使用var关键字来声明变量, JavaScript采用词法作用域, 不在任何函数内声明的变量称作全局变量, 它在JavaScript程序中的任何地方都是可见的. 在函数内声明的变量具有函数作用域, 并且只在函数内可见.
数字
  1. JavaScript不区分整数值和浮点数值,** 所有数字均以浮点数值表示.**
  2. JavaScript中除以0并不报错, 只是返回无穷大(Infinity)/负无穷大(-Infinity). 而0 / 0是没有任何意义的, 所以用NaN表示(NaN代表非数字, 可用isNaN()判断, 例如isNaN("hello")为true).
  3. JavaScript中浮点数依旧存在精度问题:(不能去比较浮点数是否相等)
        var x=0.3-0.2;
        var y=0.2-0.1;
        console.log(x);//0.09999999999999998
        console.log(y);//0.1
        x == y -->false
        x == 0.1-->false
        y == 0.1-->true
        0.07*100-->7.000000000000001
文本

转译字符

转义字符 | 含义
----|------|----
\o | NUL字符
\b | 退格符
\t| 水平制表符
\n| 换行符
\v| 垂直制表符
\f| 换页符
\r| 回车符
"| 双引号
'| 单引号
\|反斜线
\xXX| 由两位十六进制数xx指定的Latin-1字符
\uXXXX| 由四位十六进制XXXX指定的Unicode字符

字符串的使用
var s = "hello world"

  • s.charAt(0) ==> "h": 第一个字符

  • s.charAt(s.length - 1) ==> "d": 最后一个字符

  • s.substring(1, 4) ==> "ell": 第2~4个字符

  • s.slice(1, 4) ==> "ell": 同上

  • s.slice(-3) ==> "rld": 最后三个字符

  • s.indexOf("l") ==> 2: 字符l首次出现的位置

  • s.lastIndexOf("l") ==> 9: 字符l最后出现的位置

  • s.indexOf("l", 3) ==> 3: 在位置3及之后首次出现字符l的位置.

  • s.split(" ") ==> ["hello", "world"]: 分割字符串

  • s.replace("h", "H") ==> "Hello world": 替换

  • s.toUpperCase() ==> "HELLO WORLD": 转换成大写

布尔值

转换为false的变量: undefined, null, NaN, 0, -0, ""

null和undefined

null代表空指针, 通常用来表示数字, 字符串和对象的"无值状态"

undefined代表未初始化.

全局对象

全局属性: 比如undefined, Infinity和NaN

全局函数: 比如isNaN(), parseInt()和eval()

构造函数: 比如Date(), RegExp(), String(), Object()和Array()

全局对象: 比如Math和JSON

包装对象

对于字符串, 以下代码是正确的:

var s = "hello world"

var word = s.substring(1, 4)
//此时s已被封装成了对象,但是这句话执行完后,该对象立即销毁

既然字符串不是对象, 它为什么会有substring方法呢? 因为引用字符串s的属性, JavaScript就会将字符串通过调用new String(s)的方式装换成对象, 一旦属性引用结束, 这个新创建的对象就会销毁(同理于Number()和Boolean()):

var s = "test"

s.len = 4 //给对象设置属性

var t = s.len

t ==> undefined

而:

"hello" == new String("hello") ==> true//自动封装

"hello" === new String("hello") ==> false//全等,一个值,一个是对象
不可变的原始值和可变的对象引用

原始值: undefined, null, 数字, 布尔值, 字符串. 它们均不可改变.
对象: 数组和函数, 可改变

原始值的比较只要通过"=="即可(原始值所存储的内存地址是相同的, 而"=="是用于比较值是否相同, 所以对于原始值来说, 值相同+地址相同 == 它们相同)

对象的本质是引用, 所以只有引用同一个基对象(相同的内存地址)时, 它们才相同:

var o = {x: 1}, p = {x: 1}

o === p ==> false

o == p ==> false

q = o ==> Object {x: 1}//将o的引用赋值给q,此时他们指向同一个对象

q["y"] = 2 //q对象增加一个y=2的属性,此时0对象也会增加该属性

q === o ==> true

这里会造成一个困惑是: 为什么 o == p ==> false?

因为o和p的值本质上并不相同, 因为o/p中存储的是{x: 1}的引用, 而非具体的值. 而{x: 1}和另一个{x: 1}的引用是不相等的.

备注: 我们一般比较对象是否具有某个属性, in代表属性存在于实例+原型中, 而hasOwnProperty代表属性是否存在于实例中.

类型转换
字符串 数字 布尔值 对象
undefined "undefined" NaN false throws TypeError
null "null" 0 false throws TypeError
true "true" 1 new Boolean(true)
false "false" 0 new Boolean(false)
"" 0 false new String("")
"1.2" 1.2 true new String("1.2")
"one" NaN true new String("one")
0 "0" false new Number(0)
-0 "0" false new Number(-0)
NaN "NaN" false new Number(NaN)
Infinity "Infinity" true new Number(Infinity)
-Infinity "-Infinity" true new Number(-Infinity)
1 "1" true new Number(1)
{} 后面解释 后面解释 true
[] "" 0 true
[9] "9" 9 true
['a'] 使用join方法 NaN true
['a','b'] "a,b" NaN true
function(){} 后面解释 NaN true

注意:无穷大Infinity首字母必须大写,不然认为是变量

转换和相等性
进行"=="判断时, JavaScript会进行类型转换.

null == undefined ==> true

"0" == 0 ==> true

这里类型转换代表的意思是: a == b, 则a转换为b类型, 或者b转换为a类型, 再次进行比较. 所以对于null == undefined, 本质上是undefined转换为一个Object, 然后在和null进行比较.

而"0" == 0, 是将数字0转换为字符串"0", 然后再进行比较.

但可以成功进行类型转换, 不一定表示它们相等, 如undefined可转换为false, 但undefined == false的结果为false.

显示类型转换
JavaScript在需要字符串情况下, 会将变量转换为字符串; 其次, 在需要数字情况下, 会将变量转换为数字.

Number类定义的toString()方法可以接收表示转换基数的可选参数. 如果不指定此参数, 转换规则将是基于十进制:

var n = 17

n.toString() ==> "17"

n.toString(2) ==> "10001"

n.toString(8) ==> "21"

n.toString(16) ==> "11"

toFixed(): 根据小数点后的指定位数将数字转换为字符串, 它从不使用指数计数法.

toExponential(): 使用指数计数法将数字转换为指数形式的字符串, 其中小数点前只有一位, 小数点后的位数则由参数指定.

toPrecision(): 根据指定的有效数字位数将数字转换成字符串. 如果有效数字的位数少于数字部分的位数, 则转为为指数形式.

var n = 123456.789

n.toFixed(0) ==> "123457"

n.toFixed(2) ==> "123456.79"

n.toFixed(5) ==> "123456.78900"

n.toExponential(1) ==> "1.2e+5"

n.toExponential(3) ==> "1.235e+5"

n.toPrecision(4) ==> "1.235e+5"

n.toPrecision(7) ==> "123456.8"

n.toPrecision(10) ==> "123456.7890"

parseInt(): 尽可能的将字符串转换为整数, 可接收第二个可选参数, 这个参数指定数字转换的基数.

parseFloat(): 尽可能的将字符串转换为浮点数.

console.log(parseInt("111ads"))  //111

对象转换为原始值
toString(): 返回一个反映这个对象的字符串.

valueOf(): 如果存在任意原始值, 它就默认将对象转换为表示它的原始值.

JavaScript中对象到字符串的转换经历以下步骤:

如果对象具有toString()方法, 则调用这个方法. 如果它返回一个原始值, JavaScript将这个值转换为字符串, 并返回这个字符串结果.
如果对象没有toString()方法, 或者这个方法并不返回一个原始值, 那么JavaScript会调用valueOf()方法, 如果存在这个方法, 则JavaScript调用它. 如果返回值是原始值, JavaScript将这个值转换为字符串, 并返回这个字符串结果.
否则, JavaScript抛出类型错误.

var o={
            toString:function(){
                return 9;
            },
            valueOf:function(){
                return 10;
            }
        };

        console.log(""+o);//结果是“10”

对象到数字的转换经历以下步骤:

如果对象具有valueOf()方法, 返回一个原始值, 则JavaScript将这个原始值转换为数字.
否则, 如果对象具有toString()方法, 返回一个原始值, 则JavaScript将其转换并返回(如果返回的原始值是boolean类型,会转成0或1)
否则, JavaScript抛出类型错误.

var o={
            toString:function(){
                return 9;
            },
            valueOf:function(){
                return 10;
            }
        };

        console.log(+o);//结果是10

变量和作用域
JavaScript没有块级作用域, 它使用了函数作用域.

在JavaScript中, 使用var声明的全局变量是不可配置的(变量本身具有属性, 如是否可删除, 编辑, 是否只读等):

var a = "hello"

b = "world" //相当于给window对象添加了属性b

delete a ==> false

delete b ==> true

a ==> "hello"

b ==> VM920:1 Uncaught ReferenceError: b is not defined(…)

表达式和运算符

表达式

数组初始化时, 如果使用逗号(","), 则初始化为undefined:

var arr = [1,,,2]

arr.length ==> 4

arr ==> [1, undefined × 2, 2]

如果针对对象来说, 使用字面量来初始化, 那么其key/value中的key代表的是字符串:

var key = "hello"

var d1 = {key: "world"}

d1 ==> Object {key: "world"}

这里d1的声明等价于:

var d1 = {"key": "world"}

但如果使用索引来初始化, 则不一样:

var key = "hello"

var d2 = {}

d2[key] = "world"

d2 ==> Object {hello: "world"}

数组本身就是一个支持下表索引的对象:

var arr = [12, 13, 14]

arr["1"] ==> 13

arr[1] ==> 13

使用new构造出一个对象不同于使用字面量构造出一个对象, 考虑如下的代码:

var MY_APP_1 = function() {

  this.firstMethod = function() {};

  this.secondMethod = function() {};

};

 

var MY_APP_2 = {

  firstKey: functon() {},

  secondKey: function() {}

};

主要的不同点在于: 通过new, 我们可以创建多个MY_APP_1实例, 而每个实例均绑定到内部的this; 而对于MY_APP_2来说, 它仅仅只是一个变量而已.

针对MY_APP_1来说, 还有以下特殊的几点:

  1. firstMethod/secondMethod是绑定到具体的实例上, 非绑定状态下它们并不存在.

  2. 在创建具体实例后, 如果没有绑定一个具体的对象, 则this默认绑定到window对象上:

var app1 = new MY_APP_1();

app1.firstMethod();

// ERROR

// window.firstMethod();

var app2 = MY_APP_1();

// ERROR

// app2.firstMethod();

window.firstMethod();

运算符

  1. JavaScript运算符通常会根据操作数进行类型转换, 所以"3" * "5"是合法的, 为数字15.
  2. 加号既可用于字符串连接, 也可用于数字的相加, 但优先于字符串连接. 所以将数组转换为字符串时, 我们可以编写如下的代码:
var arr = [1,2,3]

"" + arr ==> "1,2,3"

但我们如果仅仅将一个字符串转换为数字, 也可以使用如下的技巧:

+"3" ==> 3

1.in运算符用于判断属性是否存在于对象实例+原型中.
2.instanceof运算符用于判断左边对象是否为右边类的实例.
3.typeof运算符用于判断对象的类型:

x typeof x
undefined "undefined"
null "object"
true 或false "boolean"
任意数字或NaN "number"
任意字符串 "string"
任意函数 "function"
任意内置对象(非函数) "object"
任意宿主对象 由编译器自身决定
  1. delete用于删除一个对象的属性, 对数组来说相当于赋值undefined:
var o = {x: 1, y:2}

delete o.x

o ==> Object {y: 2}

var arr = [11, 12, 13]

delete arr[1]

arr ==> [11, undefined × 1, 13]

语句

空语句(单独一个分号)通常用在初始化一个数组中, 例如:
for (var i = 0; i < a.length; a[i++] = 0) ;
var和function都是用来声明语句的, 而function通常有两种写法:

var f = function(x) { return x + 1; } //将表达式赋值给一个变量

function f(x) { return x + 1; }

for/in循环并不会遍历对象的所有属性, 只有"可枚举"的属性才会遍历到.

"use strict"

  1. 在严格模式中禁止使用with语句.
  2. 在严格模式中, 所有的变量都要先声明, 否则将会抛出一个引用错误异常.
  3. 在严格模式中, 调用的函数中的一个this值是undefined.
  4. 在严格模式中, 当通过call()/apply()来调用函数时, 其中的this值就是通过call()或apply()传入的第一个参数(在非严格模式中, null和undefined值被全局对象和转换为对象的非对象值所代替)
  5. 在严格模式中, 给只读属性赋值和给不可扩展的对象创建新成员都将抛出一个类型错误异常.
  6. 在严格模式中, 传入eval()的代码不能在调用程序所在的上下文中声明变量或定义函数, 而在非严格模式中是可以这样做的.
  7. 在严格模式中, 函数里的arguments对象拥有传入函数值的静态副本, 即不可修改:
"use strict"

 

function f(arr) {

  f.arguments[0][0] = 11;

}

var arr = [1, 2, 3];

f(arr);

console.log(arr);

这里代码将会报错.

针对delete, 后跟非法的标识符将抛出一个语法错误异常; 如果试图删除一个不可配置的属性将会抛出一个类型错误异常.

参考文献:https://my.oschina.net/voler/blog/807507

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,191评论 0 4
  • 1.HTML DOM (Document Object Model) document.getElementByI...
    廖马儿阅读 1,395评论 0 17
  • 我们在感叹岁月的老去的时候,也该感谢时光对我们的给予。自古最难是两全,许下的诺言没有实现便就是欠下的债,我们经常在...
    流年_9df3阅读 280评论 0 1
  • 沈华立,天贝车业,盛和塾224期学员,【日精打卡第110天】 《六项精进》1遍共210遍 《大学》1遍共210遍 ...
    沈华立阅读 106评论 0 0
  • 这是我在简书的第一篇小文,手机夜打 去年年底,也就是几天前,我表白了 很开心,并不是因为结果(结果是婉拒(不过婉拒...
    现在就是哦哈哈阅读 102评论 0 1