【JS】1--基本语法和数据类型

语法和数据类型


本章节复习的是JS中的基本语法,变量声明,数据类型和字面量。

首先要记住:JavaScript 对大小写敏感,即 varatt;varAtt 是两个不同变量。
入门

一. js是什么?

(js即javascript,它是一种轻量级的脚本语言。运行在浏览器客户端.)

二. js引入方式

  • a.内嵌式
    所有js代码写到一个<script></script>,
    此script标签可以放到html的任何地方
<script type="text/javascript">
    js代码
</script>
  • b.外链式
    所有的js代码写到一个外部js文件内(该文件后缀名为.js),
    在html内通过script上的src属性引入过来。
    <script src="xxx.js"></script>
    //导入外部js文件
  • c.事件引入
    在开始标签上通过加事件引入js代码
  <button onclick="js代码">按钮</button>

<script>元素有下列 8 个属性。

 async:可选。表示应该立即开始下载脚本,但不能阻止其他页面动作,比如下载资源或等待其
他脚本加载。只对外部脚本文件有效。
 charset:可选。使用 src 属性指定的代码字符集。这个属性很少使用,因为大多数浏览器不
在乎它的值。
 crossorigin:可选。配置相关请求的CORS(跨源资源共享)设置。默认不使用CORS。crossorigin= "anonymous"配置文件请求不必设置凭据标志。crossorigin="use-credentials"设置凭据
标志,意味着出站请求会包含凭据。
 defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。
在 IE7 及更早的版本中,对行内脚本也可以指定这个属性。
 integrity:可选。允许比对接收到的资源和指定的加密签名以验证子资源完整性(SRI,
Subresource Integrity)。如果接收到的资源的签名与这个属性指定的签名不匹配,则页面会报错,
脚本不会执行。这个属性可以用于确保内容分发网络(CDN,Content Delivery Network)不会提
供恶意内容。
 language:废弃。最初用于表示代码块中的脚本语言(如"JavaScript"、"JavaScript 1.2"
或"VBScript")。大多数浏览器都会忽略这个属性,不应该再使用它。
 src:可选。表示包含要执行的代码的外部文件。

三. 输出方式

alert()//警告框
document.write(内容)//向文档内部写入内容
console.log()//控制台日志输出

window对象的方法

  1. alert
      alert() 警告框
     无返回值
  2. confirm
     confirm() 确认对话框
       有返回值
       返回值:布尔值
       点击【确认】按钮,返回true,点击【取消】按钮,返回false
  3. prompt
      prompt(提醒文本,【默认】) 提示输入对话框
       返回值:字符串 / null
      点击【确认】按钮,返回输入框中的值(字符串类型),点击【取消】按钮,返回null
    注:
    console.log();控制台输出
    document.write();页面输出

四. 注释

// 单行注释
/*
多行注释
*/

五. 变量 常量(声明)

a. 变量命名规范

 1. 变量的名字又叫做“标识符”,必须以字母、下划线、美元符号$开头,后面可以是字母、下划线、美元符号或数字。
 2.变量区分大小写
 3.变量名不能使用关键字和保留字

b. 声明变量

JavaScript有三种声明方式:

  • var 声明一个变量(函数作用域),可赋一个初始值。
  • let 声明一个块作用域的局部变量,可赋一个初始值。
  • const 声明一个块作用域的只读命名的常量。

c. 初始化变量

  • var a=1,声明局部变量和全局变量。
  • a=1,声明一个全局变量,且在严格模式报错,不应该使用。
  • let a=1,声明一个块作用域的局部变量。

1. var 声明

a. 函数作用域

关键的问题在于,使用 var 操作符定义的变量会成为包含它的函数的局部变量。比如,使用 var
在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁:

function test() { 
 var message = "hi"; // 局部变量
} 
test(); 
console.log(message); // 出错!
b.var在全局作用域中声明的变量会成为 window 对象,let不会

与 var 关键字不同,使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)。

var name = 'Matt'; 
console.log(window.name); // 'Matt' 
let age = 26; 
console.log(window.age); // undefined 

不过,let 声明仍然是在全局作用域中发生的,相应变量会在页面的生命周期内存续。因此,为了避免 SyntaxError,必须确保页面不会重复声明同一个变量。
若想将var定义的变量成为全局变量,则可以这样:

function txt(){
    a =1;//全局变量
}
txt();
console.log(a)//1
c. var 声明提升

使用 var 时,下面的代码不会报错。这是因为使用这个关键字声明的变量会自动提升到函数作用域顶部:

function foo() { 
 console.log(age); 
 var age = 26; 
} 
foo(); // undefined 

之所以不会报错,是因为 ECMAScript 运行时把它看成等价于如下代码:

function foo() { 
 var age; 
 console.log(age); 
 age = 26; 
} 
foo(); // undefined 

这就是所谓的“提升”(hoist),也就是把所有变量声明都拉到函数作用域的顶部。此外,反复多次
使用 var 声明同一个变量也没有问题:

function foo() { 
 var age = 16; 
 var age = 26; 
 var age = 36; 
 console.log(age); 
} 
foo(); // 36 


1. let 声明

a. 块作用域

let 跟 var 的作用差不多,但有着非常重要的区别。最明显的区别是,let 声明的范围是块作用域,而 var 声明的范围是函数作用域。

if (true) { 
 var name = 'Matt'; 
 console.log(name); // Matt 
} 
console.log(name); // Matt 
if (true) { 
 let age = 26; 
 console.log(age); // 26 
} 
console.log(age); // ReferenceError: age 没有定义

在这里,age 变量之所以不能在 if 块外部被引用,是因为它的作用域仅限于该块内部。块作用域
是函数作用域的子集,因此适用于 var 的作用域限制同样也适用于 let。
let 也不允许同一个块作用域中出现冗余声明。这样会导致报错:

var name; 
var name; 
let age; 
let age; // SyntaxError;标识符 age 已经声明过了

当然,JavaScript 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标
识符不会报错,而这是因为同一个块中没有重复声明:

var name = 'Nicholas'; 
console.log(name); // 'Nicholas' 
if (true) { 
 var name = 'Matt'; 
 console.log(name); // 'Matt' 
} 
let age = 30; 
console.log(age); // 30 
if (true) { 
 let age = 26; 
 console.log(age); // 26 
} 

对声明冗余报错不会因混用 let 和 var 而受影响。这两个关键字声明的并不是不同类型的变量,
它们只是指出变量在相关作用域如何存在。

var name; 
let name; // SyntaxError 
let age; 
var age; // SyntaxError 

注意

  • 若没有为变量赋初始值,则值默认为 undefined
let a;
console.log(a);  // undefined
  • 若没有声明变量而直接使用,会抛出 ReferenceError错误;
console.log(b);  // Uncaught ReferenceError: b is not defined
  • 当变量值为 undefined时,布尔值环境会当做 false,数值环境会当做 NaN
var a;
if(!a){
console.log('a为undefined');  // a为undefined
}
a +  1; // NaN
  • 当变量值为 null时,布尔值环境会当做 false,数值环境会当做 0
let a =  null;

if(!a){
    console.log('a为unll');  // a为unll`
 }
a +  1; // 1

d. 变量作用域

全局变量:即声明在函数之外,当前文档所有地方都可以访问;
局部遍历:即声明在函数内部,仅在当前函数内可以访问;

(在ES5之前没有语句块作用域的概念,并只能使用 var进行声明,用 var声明的变量,在函数内和全局都可以访问,而在ES6开始,将只能在声明的作用域中使用.)

if(true){
     var a =  1;
 }
 a;  // 1
if(true){
     let b =  2;
 }
b;  // ReferenceError: b is not defined
变量声明提前(ES5 之前)

即将变量的声明提升到函数或语句的顶部,并返回 undefined直到变量被初始化操作。
千万注意:ES5 以及之前,才有变量声明提前,在ES6开始就不存在变量提升。

// ES5及之前
console.log(a);  // undefined
var a =  1;
console.log(a);  // 1
// ES6开始`
console.log(b);  // Uncaught ReferenceError: b1 is not defined
let b =  2;
console.log(b);  // 2

函数提升

函数声明有两种方式:函数声明函数表达式两种方式:

// 函数声明
f();              // hi leo
function(){
    console.log('hi leo');
};
// 函数表达式
g();                          // Uncaught TypeError: g is not a function
var g =  function(){           // 换成 let 声明也一样
    console.log('hi leo');
}

暂时性死区

上面说了var会有变量提升,而let却没有。如:

// name 会被提升
console.log(name); // undefined 
var name = '伍叁'; 
 
//------------------
// age 不会被提升
console.log(age); // ReferenceError:age 没有定义
let age = 18;

全局变量

全局变量默认是全局对象( window)的属性,常常使用 window.variable语法来设置和访问全局变量。
这边还需要记住:

  • ES5之中,顶层对象的属性等价于全局变量(浏览器环境中顶层对象是 window,Node中是 global对象);

  • ES6之中var/ function声明的全局变量,依然是顶层对象的属性,但是 let/ const/ class声明的全局变量不属于顶层对象的属性,即ES6开始,全局变量和顶层对象的属性是分开的。

// ES5
var a =  'leo';
window.a;            // 'leo'
// ES6
let b =  'leo';
window.b;            // undefined

常量和 const

ES6之后我们可以使用 const来声明一个只读的常量,并且在声明时必须赋值,之后在相同作用域中不能赋值不能重新声明,否则报错。

const a;
// Uncaught SyntaxError: Missing initializer in const declaration
const b =  'leo';
b =  'hi';
// Uncaught TypeError: Assignment to constant variable.
function f(){
    const a1 =  'hi';
    console.log(a1);
}
f();  // 'hi'
    const a1 =  'hi leo';
    a1;  // "hi leo"

尽管 const声明的变量不能直接修改值,但是对于对象和数组,却是不受保护可以修改的:

const a =  {name:'leo',age:25};
a.name =  'pingan';  // a => {name: "pingan", age: 25}
const b =  ['hi',  'leo'];
b[1]  =  'pingan';  // b => ["hi", "pingan"]

六. 数据结构和数据类型

数据类型

JavaScript中一共分为7种不同类型:

  • 六种原型数据类型:
  • 1.Boolean : 布尔值,true和false;
  • 2.null : 对大小写敏感(即 null/ Null/ NULL完全不同);
  • 3.undefined : 空类型,变量未定义时候的值;
  • 4.Number : 数字类型,如 100;
  • 5.String : 字符串类型,如'hi pingan';
  • 6.Symbol(ES6新增) : 表示一种唯一且不可变的数据;
  • 以及Object对象类型

数据类型转换

由于JavaScript是门动态类型语言,因此在开发过程可以不需要指定数据类型,在执行时会自动转换:

var a =  100;
a =  'hi leo';  // 这样不报错

另外还有:

let a1 =  '10';
let b1 =  20;
a1 + b1;  // 30
let a2 =  'leo '  +  10  +  ' age';  // leo 10 age
'10'  -  5; // 5
'10'  +  5; // 105

转换字符串为数字小技巧(连接符+)
小技巧很多,这里说个最简单的:

// 这样不会使两个数字计算总和:  
'1.1'  +  '1.2';  // '1.11.2'
// 实际上要这样:
+'1.1'  +  +'1.2';  // 2.3

七. 字面量

字面量是用来表示如何表达这个值,简单理解就是变量赋值时右边的都是字面量。比如:

let a =  'hi leo';

hi leo为字符串字面量, a为变量名。
字面量分为七种:

  • 1.数组字面量
  • 2.布尔字面量
  • 3.浮点数字面量
  • 4.整数字面量
  • 5.对象字面量
  • 6.正则字面量
  • 7.字符串字面量

1. 数组字面量

使用数组字面量创建数组的时,指定元素的值,并作为数组的初始化,从而确定数组长度。

let a =  ['hi','leo','hello','pingan'];
a[1];  // 'leo'
a.length;  // 4

若使用多余逗号,作为数组字面量,则值为 undefined,并且数组长度也会正常计算:

let a =  ['hi',  ,'leo'];
a[0]; // 'hi'
a[1]; // undefined
a.length;  // 3

2. 布尔字面量

只有 truefalse

let a =  true;

3. 整数字面量

整数可以用十进制(基数为10)、十六进制(基数为16)、八进制(基数为8)以及二进制(基数为2)表示。

4. 浮点数字面量

浮点数字面量组成:

  • 一个十进制的整数,可以带正负号;
  • 小数点
  • 小数部分(只能十进制)
  • 指数部分
let a =  3.14; // 3.14
let b =  -.001;  // -0.001
let c =  -3.14e+12;  // -3.14*1012
let d =  .1e-23;// 0.1*10 - 23 = 10-24 = 1e-24

5. 对象字面量

对象字面量是由 {}包含一个或多个 键:值 对的列表:

let a1 =  'hi leo';
let a2 =  function(){  return  'my name is pingan'  };
let obj =  {
n1 :  'pingan',
n2 : a1,
n3 : a2()
}
obj;  // {n1: "pingan", n2: "hi leo", n3: "my name is pingan"}

也可以使用任意数字或字符串作为对象属性的名字,但必须用 ''引号包裹:

let obj =  {
    ""  :  "hi leo",
    "!"  :  "hi pingan",
    2  :  'hi number'
}
obj;                    // {2: "hi number", "": "hi leo", !: "hi pingan"}
obj[""];              //  "hi leo"
obj[2];             // "hi number"

6. 正则字面量

使用字符被正斜杠“ /”围起来的表达式:

var a =  /ab+c/;

7. 字符串字面量

使用单引号( '')或者双引号( "")括起来的字符串:

let a =  'leo';
a.length; // 3

ES6中新增了模板字符串,作用于:

  • 方便拼接字符串

  • 有效实现字符串换行

  • 防止注入攻击

  • 建立基于字符串的高级数据抽象

// 拼接字符串
let name =  'leo';
let a =  `
    hi ${name}
`;
a;  // hi leo
// 换行`
let b =  `
    hi
    leo
`;
b;
// "
//     hi
//     leo
// "

常用特殊字符:

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

推荐阅读更多精彩内容