从零开始学JavaScript 1 ——基本概念

概念

  1. JavaScript的组成

image.png

  • 核心———— ECMAScript
  • 文档对象模型———— DOM
  • 浏览器对象模型———— BOM
  1. W3C(World Wide Web Consortium,万维网联盟):负责制定 Web 通信标准
  2. ECMA-262第6版,俗称ES6、ES2015或ES Harmony;ES6正式支持了类、模块、迭代器、生成器、箭头函数期约、反射、代理和众多的数据类型

在HTML中使用

区分< script >属性

用于在HTML页面中插入JavaScript;可在页面嵌入或外部引入

特点:

  • 代码执行顺序:< script > 元素内部js代码从上到下依次解释;
  • 阻塞页面:< script > 元素内部js代码执行完毕,页面才会被浏览器加载或显示,也就是说,解析JavaScript代码或文件时,页面的处理也会暂时停止
  • 顺序:浏览器按照< script > 元素在页面出现的先后顺序对它们依次进行解析,在第一个 < script >元素内宿包含的代码解析完成后,第二个< script >包含的代码才会解析,然后是第三个、第四个……(包含defer、async属性除外)
  • 位置:一般放在 body 元素中页面内容的后面(因为按照传统做法放在 head 标签中,会导致浏览器页面出现明显的延迟)

属性:

  • async :异步脚本——立即下载脚本,不保证先后顺序,脚本之间互不依赖。页面不需要等待脚本下载和执行,从而异步加载页面其他内容。建议异步脚本不要再加载期间修改DOM
  • *charset : 指定字符集
  • crossorigin:配置相关请求的cors(跨域资源共享)设置。默认不使用cors。crossorigin=”anonymous”配置文件请求不必设置凭据标志。crossorigin=”use-credentials”设置怕凭据标志,意味着出站请求会包含凭据。
  • defer : 延迟脚本——脚本延迟至整个页面完全被解析和显示之后再执行,脚本执行时不会影响页面的构造——立即下载,延迟执行
  • integrity:允许比对接收到的资源和指定的加密前面以验证子资源完整性(SRI,
    Subresource Integrity)。如果接收到的资源的签名与这个属性指定的签名不匹配,则页面会报错,
    脚本不会执行。这个属性可以用于确保内容分发网络(CDN,Content Delivery Network)不会提
    供恶意内容。
  • src : 外部文件链接
  • *type : 脚本语言类型(MIME类型);默认为 text/javascript;如果这个值是module,则代码会被当成ES6模块,而且只有这种时候代码中才能出现import和export关键字。

行内代码与外部文件

比起行内代码,使用外部文件来包含JavaScript代码有以下优点:

  • 可维护性
  • 可缓存(如果有两个页面都使用同一个文件,那么这个文件只需被下载一次)
  • 适应未来

< noscript >

不支持JavaScript时浏览器显示的内容,例:

<noscript>
    <p>本页面需要浏览器支持(启用)JavaScript。</p>
</noscript>

语言基础

语法

  • 注意点:区分大小写、函数名不能使用关键字、推荐使用驼峰命名、
    第一个字符必须是一个字母 下划线( _ )或一个美元符号($)

  • 严格模式: 在脚本顶部添加代码
    “use strict”;

关键字和保留字

若用关键字作标识符,会导致 “Identifier Expected” 错误

变量

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

换句话说,每个变量仅仅是一个用于保存值的占位符而已。

给未经声明的变量赋值 在严格模式下会抛出 ReferenceError 错误。

有三个关键字可以声明变量:var、const和let;var适用于ECMAScript所有版本,const和let只适用于ECMAScript6及更晚的版本。

var 关键字:

  • 用于定义变量,不限类型
  • 不初始化的情况下,变量会保存一个特殊值 undefined
  • 作用域:var定义的是包含它的函数的的局部变量,该变量将在函数退出时被销毁
  • 在函数内定义变量省略var操作符,会创建一个全局变量,最好不要这样做,不利于维护
  • 声明提升:使用var声明的变量会自动提升到函数作用域的顶部;反复多次使用var声明同一个变量也没问题

let 声明:

let与var的区别:

  • let声明的范围是块作用域,而var是函数作用域(块作用域是函数作用域的子集);
  • let不可在同一块作用域中重复声明同一个变量;
  • let声明的变量不会提升
  • let在全局作用域中声明的变量不会成为window对象(let声明仍然是在全局作用域中发生的)
  • for循环中:使用var定义的迭代变量会渗透到循环体外部;使用let定义的迭代变量的作用域仅限于for循环体内部

const声明:

const与let的区别:

  • cosnt在声明时必须初始化变量,且不能修改
  • 不能用const来声明迭代变量
  • const声明的限制只适用于它指向的变量的引用。换句话说,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制

变量的最佳实践: const优先,let次之,不使用var

数据类型

6+1 = 7 种

ES6 基本数据类型(6个): Number, String, Boolean, null, undefined, symbol (ES6新增)

引用数据类型:
object

typeof 操作符

用于鉴定给定变量的数据类型

但无法完全区分 null 和 object,调用 typeof 都返回“object”;
因为特殊值 null 被认为是一个空的对象的引用

typeof "some string"; //"string"
typeof 95; //"number"
typeof undefined; // "undefined"
typeof true; // "boolean"
function Fun(){ alert('函数') };
typeof Fun; //"function"
// 特殊
var obj = {a:1};
typeof obj; // "object"
typeof null; // "object"

Number

  1. 浮点数值

    var floatNum1 = 0.1;
    var floatNum2 = .1; // 有效,不推荐
    保存浮点数值需要的 内存空间 是保存整数值的两倍;所以ES总是想方设法的把值转换为整数

    对于极大或绩效的数值,可用 e 表示法(科学计数法)

    var floatNum = 3.125e7 // 等于31250000(3.125*10ⁿ,n=7)
    浮点的最高精度是17位小数,算数计算时其精确度不如整数。例如,0.1加0.2的结果不是0.3,而是0.30000000000000004,所以:

    if(a+b == 0.3){ // 不要做这样的测试!
    alert(“You got 0.3.”)
    }

  2. 数值范围

    由于内存的限制,ECMAScript并不能保存所有的数值

    大多数浏览器支持的数值范围在 5e-324 ~ 1.7976931348623157e+308 之间,超过则会被转换为 Infinity,此时无法再进行计算。

    isFinite() 用以判断是否在正常范围内

  3. NaN ( Not a Number )

    一个特殊的数值,用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。
    NaN不等于包括NaN在内的任何值

    console.log(NaN == NaN); // false

    isNaN(a) 用于判断a是否“不是数值”

  4. 数值转换

    Number()

    Number(true) // 1
    Number(false) // 0
    Number(null) // 0
    Number(undefined) // NaN
    Number('011') // 11
    Number('Hello') // NaN
    //特殊:如果参数是包含十六进制格式如“0xf”的字符串,则会转换为与该十六进制值对应的十进制整数值
    

    parseInt()

    parseInt("1234abc") // 1234
    parseInt("22.5") // 22
    parseInt("0xf") //15
    parseInt("0xAF",16) // 175
    

    可接收两个参数,第一个需要转换的对象,第二个转换成多少进制的数值;不传第二个参数可根据数值形式自动转换

    区别:Number()对空字符串返回0,parseInt()返回NaN

    parseFloat()

    与parseInt()类似,是对浮点数进行转换,直到第二个小数点失效;并且只解析 十进制 值(十六进制值始终会返回0)。

String

以双引号(””)、单引号(”)或反引号(“)表示的由零或多个16位Unicode字符组成的字符序列

  1. 字符字面量

    转义序列,用于表示非打印字符,或者具有其他用途的字符。
    一般用 \ 表示

    字面量 含义
    \n 换行
    \t 制表
    \b 退格
    \r 回车
    \f 换页
    \ \ 反斜杠(\)
    \ ‘ 单引号
    \ “ 双引号
    \ ` 反引号
    \ xnn 以十六进制代码nn表示的一个字符(其中n为0 ~ F)。例如,\x41表示”A”
    \unnnn 以十六进制代码nnnn表示的一个Unicode字符,其中n为0 ~ F。例如,\u03a3表示希腊字符 ∑
  2. 转换为字符串

    toString() 不适用于null和undefined;

    多数情况下,调用toString()方法不必传参数;

    可传一个参数,用以表示输出数值的底数,默认十进制,比如:

     let num = 10;
     alert(num.toString()); // "10"
     alert(num.toString(2)); // "1010"
     alert(num.toString(8)); // "12"
    

    String() 适用于null和undefined;

     let value1 = null;
     alert(String(value1)); //"null"
    

Boolean

true    false
转型函数 Boolean(),可对任意数据类型调用该函数,且都会返回一个Boolean值
Boolean('some string'); // true
Boolean(""); // false
Boolean(1); // true
Boolean(50); //true
Boolean(0); // false
Boolean(NaN); // false
Boolean(window); // true (任何对象)
Boolean(null); // false
Boolean(undefined); // false
在运用流语句(如 if 语句),会自动执行相应的 Boolean 转换

null

空对象指针
一般用于 定义的变量用于 保存对象,则最好将该变量初始化为null而不是其他值
typeof null; // 'object'
null == undefined; // true (undefined的值是派生于null值的)

undefined

表已声明变量但未对其加以初始化

symbol

表示一个独一无二的值
创建:
const a = Symbol();
const b = Symbol(); //任何人在任何作用域内都无法重新创建初这个值
console.log(a); //Symbol(), 此时得到了一个在内存中独一无二的值

尽管a和b都是使用Symbol()创建出来的,但是它们在内存中看起来却是这样的
image.png

a!==b; //a和b是两块内存的引用
const c = a; // 把a里保存的地址保存在c变量值
a === c; // 指向同一块内存

这种行为与对象遵循相同的规则,如

var a = {}
var b = {}

a!==b; //a和b各自被分配了不同的内存,因此它们保存了不同的地址


var c = a; //借助变量a,变量c拿到了a指向的那个对象的地址,因此两者相等
a === c;

但是对于同为基本数据类型的字符串来说,它不遵循类似的规则,如

image.png

两者指向内存中同一块内存地址

不能使用new关键字:
const a = new Symbol(); //报错, Symbol is not a constructor
Symbol类型的值也不参与运算
可以接收一个字符串参数便于区分


//使用场景
1. 作为属性名,可以保证属性不重名
2. 定义常量

cloud.tencent.com/developer/a…

object

一组数据和功能的集合
可通过 new 来创建对象实例
var o = new Object()
Object的每个实例都有下列属性和方法:
    constructor:保存着用于创建当前对象的函数(构造函数)
    hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而非在实例的原型中)是否存在;作为参数的属性名必须以字符串的形式指定
    isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型
    propertyIsEnumerable(propertyName):用于检查给定的属性是否能用 for-in 来枚举;作为参数的属性名必须以字符串的形式指定
    toLocaleString():返回对象的字符串表示,该字符串与执行环境地区对应
    toString():返回对象的字符串表示
    valueOf():返回对象的字符串、数值或布尔值表示;通常与toString()方法的返回值相同
    
ECMAScript中Object是所有对象的基础,因此所有对象都具有这些基本的属性和方法

操作符

操作数据值

一元操作符

只操作一个值
1. 递增和递减
    // 前置
var age = 29;
++age; // age等于30,改变了age值,相当于 age = age + 1
--age; // 29
当语句中包含其他操作时,变量的值是在语句被求值以 前 改变的。例
var age = 29;
var anotherAge = --age + 2;
alert(age); // 28
alert(anotherAge); //30
    // 后置
var age = 29;
age++; //30
当语句中包含其他操作时,变量的值是在语句被求值以 后 改变的。例
var num1 = 2; 
var num2 = 20; 
var num3 = num1-- + num2; // 等于 22 
var num4 = num1 + num2; // 等于 21

总结: 
a. 当一个语句中递增或递减时唯一一个操作时,前置和后置都适用;如果包含其他操作,最好用前置
b. 递增递减操作还可用于字符串、布尔值、浮点数值和对象,过程中可能涉及类型的转换

2. 一元加和减操作符
var num = 25;
num = +num; // 25
一元加放在数值前面不会对结果产生任何影响,但是
放在非数值类型前面,相当于用了Number()来转型,例
var s1 = "01"; 
var s2 = "1.1"; 
var s3 = "z"; 
var b = false; 
var f = 1.1; 
var o = {
    valueOf: function() { return -1; } 
};

s1 = +s1; // 值变成数值 1 
s2 = +s2; // 值变成数值 1.1 
s3 = +s3; // 值变成 NaN 
b = +b; // 值变成数值 0 
f = +f; // 值未变,仍然是 1.1 
o = +o; // 值变成数值-1
一元减主要用于表负数
var num = 25;
num = -num; //-25
一元减应用于非数值时,执行与一元加相同的规则,再转换为负数

位操作符( 了解 )

位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。

布尔操作符

测试两个值的关系

1. 逻辑非 ( ! )
逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再 对其求反
两个感叹号(!!)就是“负负得正”
2. 逻辑与 ( && )
第一个操作数为false,就不会对第二个操作数求值
3. 逻辑或 ( || )
第一个操作数为false,才会对第二个操作数求值

乘性操作符

乘法* 、 除法/ 、 求模(余数)%

加性操作符

操作数值的加法或减法
操作加法时,如果其中一个操作数是字符串,则进行字符串的拼接

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

每个加法操作是独立进行的

关系操作符

< 、 > 、 <= 、 >=

进行两个操作数的数值或字符编码值的比较,期间可能涉及到类型转换

注:

  • 比较英文单词时,可将两个单词都转为小写形式,得出更为正确的结果(大写字母的字符编码全部小于小写字母的字符编码);
  • 比较数字字符串时,需保证至少一个是 number 类型;
  • 任何操作数与 NaN 进行比较,结果都是 false;

相等操作符

相等 == ; 不相等 !=

全等 === ;不全等 !==

相等和不相等是需强制转型的,全等和不全等比较的是未转型的操作数

null == undefined; // true
null === undefined; // false

条件操作符

三目运算符
var a = trueOrFalse ? b : c ;

赋值操作符

=

复合赋值(为了简化赋值操作)
*=、 /=、%=、+=、-= …

逗号操作符

一条语句中执行多个操作
var num1=1, num2=2, num3=3;

语句

if语句

if(…) … else …

循环语句

do-while

后测试循环语句,即在对条件表达式求值之前,循环体内的代码至少会被执行一次

do {
    statement
} while ( expression )

常用于循环体中代码至少要被执行一次的情况

while

前测试循环语句,先对条件求值,满足条件则进入循环体,不满足则不执行循环体

while ( expression ) statement

for

前测试循环语句;

可在循环前初始化变量、定义循环后要执行的代码

for (initialization; expression; post-loop-expression) statement;
// 这三个表达式可以省略;
// 若全部省略 for(;;){...},则为一个无限循环;若只给出了控制表达式 for(;i<count;){...},则转换成了while循环
示例:
var count = 10;
for (var i = 0; i < count; i++){
    alert(i)
}

使用 while 循环做不到的,使用 for 循环同样也做不到;for 循环只是把与循环有关的代码集中在了一个位置。

for-in

精准的迭代语句;可以用来枚举对象的属性

for (poperty in expression) statement
示例:
for (var propName in window) {
    document.write(propName)
}; // 循环显示window对象的所有属性

注:因为ECMAScript对象的属性没有顺序,所以 for-in 循环输出的属性名的顺序是不可预测的

label语句

一般与for循环语句配合使用,用以跳出循环(多发生在循环嵌套的情况下)

label: statement

例:

start: for( let i = 0; i < 10; i++){
    for(let j = 0; j < 10; j++){
        if(i === 5 && j === 5){
            break start;
        }
    }
};

// 此例在i=5和j=5时跳出整个循环;
// 该例中的 start 标签可以在将来由 break 和 continue 语句引用

break 和 continue 语句

都用于在循环中精确地控制代码的执行

break   立即退出循环
continue  立即退出循环,但退出循环后会从循环的顶部继续执行

with 语句

用以简化多次编写同一对象的工作,例

var qs = location.search.substring(1);
var hostName = location.hostName;
var url = location.href;
// 以上代码都包含location对象,可用with语句改写:
with(location){
    var qs = search.substring(1);
    var hostName = hostName;
    var url = href;
}
// with 语句的代码块内部,每个变量首先被认为是一个局部变量,而如果在局部环境中找不到该变量的定义,就会查询location对象中是否有同名的属性;如果发现了同名的属性,则以location对象属性的值作为变量的值
// 严格模式下不允许使用
// 大量使用with语句会导致性能下降,所以不建议使用

switch 语句

类似 if 语句的流控制语句

switch (expression) {
    case value: statement 
        break;
    case value: statement
        break;
    case value: statement 
        break; 
    case value: statement
        break;
    default: statement
}
// switch语句在比较值时使用的是全等操作符,因此不会发生类型转换

函数

封装 >> 调用
使用 function 关键字来声明,后跟一组参数以及函数体
function funName(arg0, arg1, ..., argN){
    statements
};
可通过 return 语句实现返回值 (会直接停止函数运行)

理解参数

ECMAScript 中的参数在内部是用 一个数组 来表示的;在函数体内可通过 arguments 对象来访问这个参数数组

function sayHi(name,message){
    alert("Hello " + name + ", " + message)
};
// 等同于
function sayHi(){ 
    alert("Hello " + arguments[0] + "," + arguments[1]); 
};

这说明 命名的参数只提供便利,但不是必需的

arguments的值永远与对应命名参数的值保持同步,但两个值的内存空间是独立的,即

function doAdd(num1, num2) {
    arguments[1] = 10;  // 严格模式下不适用(不能直接赋值)
    alert(arguments[0] + num2); 
};
// 修改了 arguments[1], 也修改了 num2

变量、作用域与内存

原始值与引用值

  1. 概念:

    原始值:按值访问

    引用值:保存在内存中的对象。保存引用值的变量是按引用(by reference)访问的。

    JavaScript不允许直接访问内存位置,因此也就不能直接操作对象所造的内存空间。在操作对象时,实际上操作的是对该对象的引用(reference)而非实际的对象本身。

  2. 动态属性:

    只有引用值能添加动态属性;如果使用的是new关键字,则JavaScript会创建一个Object类型的实例,但其行为类似原始值。

  3. 复制值:

    原始值的复制会形成两个独立的变量,互不干扰。

    引用值的复制也会形成两个变量,但复制的值实际上是一个指针,它指向存储在堆内存中的对象。操作完成后,两个变量实际上指向同一个对象,因此一个对象上面的变化会在另一个对象上反映出来。

let obj1 = new Object();
let obj2 = obj1; 
obj1.name = "Nicholas";
console.log(obj2.name); // "Nicholas

如图所示:

企业微信截图_16878537394140.png

  1. 传递参数
    ECMAScript中所有函数的参数都是按值传递的(传递对象参数时也是如此,不能因为在函数内部设置属性的变化反映到了函数外部的对象,就任务对象参数时按引用传递的)。如:
function setName(obj) {
    obj.name = "Nicholas";    
    obj = new Object();   
    obj.name = "Greg";
} 
 
let person = new Object(); 
setName(person); 
console.log(person.name);  // "Nicholas" 
// 函数中参数的值改变之后,原始的引用仍然没变;
// 当obj在函数内部被重写时,它变成了一个指向本地对象的指针,这个本地对象在函数执行结束时就被销毁了。

ECMAScript中函数的参数就是局部变量。

  1. 确定类型

    原始值用typeof

    引用值用instanceof,例 person instanceof Object

执行上下文与作用域

内部上下文可以通过作用域链访问外部上下文中的一切,但外部上下文无法访问内部上下文中的任何东西。

作用域链增强

有两种情况,会将作用域链前端临时添加一个上下文,这个上下文在代码执行后会被删除

  • try/catch语句中的catch块
  • with语句

变量声明

使用var的函数作用域声明

使用var声明变量时,变量会被自动添加到最接近的上下文。

存在“声明提升

使用let的块级作用域声明
注意
  1. 如果变量未经声明就被初始化了,那么它就会自动被添加到全局上下文。(未经声明而初始化变量是JavaScript编程中一个非常常见的错误,会导致很多问题。为此,在初始化变量前一定要先声明变量。在严格模式下,未经声明就初始化变量会报错。)

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYsbk9Te' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片