js基础
DOM (Document Object Model)(文档对象模型)是用于访问 HTML 元素的正式 W3C 标准。
JavaScript 可以通过不同的方式来输出数据:
- 使用 window.alert() 弹出警告框。
- 使用 document.write() 方法将内容写到 HTML 文档中。针对整个文档。如果在文档已完成加载后执行 document.write,整个 HTML 页面将被覆盖。
- 使用 innerHTML 写入到 HTML 元素。操作某一id元素。document.getElementById("demo").innerHTML = "段落已修改。";
- 使用 console.log() 写入到浏览器的控制台。
js字面量
数字(Number)字面量 可以是整数或者是小数,或者是科学计数(e)。
字符串(String)字面量 可以使用单引号或双引号:
数组(Array)字面量 定义一个数组:
对象(Object)字面量 定义一个对象:
函数(Function)字面量 定义一个函数:
变量var
变量是一个名称。字面量是一个值。
JavaScript 中,常见的是驼峰法的命名规则,和java类似,如 lastName (而不是lastname)。
可以在一条语句中声明很多变量。该语句以 var 开头,并使用逗号分隔变量即可。一条语句中声明的多个变量不可以同时赋同一个值:
es6: let 和 const
var声明的变量的作用域是整个封闭函数。
es6中var常被let代替,let允许你声明一个作用域被限制在块级中的变量、语句或者表达式,单次使用,用完清空。在Function中局部变量推荐使用let变量,避免变量名冲突。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
const 关键字用来声明 JavaScript中的常量(与变量相对,不可修改,但同样是用于存储信息的"容器"。),常量的值不能通过重新赋值来改变,并且不能重新声明。
js函数传参时,实参个数如果比形参少,那么剩下的默认赋值为 undefined,如果实参传的比形参数量多,那么是全部都会被传进去的,只不过没有对应的形参可以引用(但可以用 arguments 来获取剩下的参数)。
变量与函数重名的时候,变量生效,这涉及到了变量和函数的预解析:
- 变量声明会被顶置,函数声明也会被顶置且比变量更先声明。
- 变量的声明和赋值语句一起写时,JS引擎在解析时,会将其拆成声明和赋值2部分,声明置顶,赋值保留在原来位置。
- 声明过的变量不会再重复声明。但可以被重复赋值
预编译过程中形成的作用域链的查找顺序是由里向外,JS执行顺序是自上往下的。因此下面代码中a = 1时,if的作用域中并不存在a变量,所以会将1赋值给全局中的a变量。
var a = 0; if(true){ a = 1; //作用域中不存在a变量,因此会通过作用域链向外查找,找到全局中的a变量,并将1赋值 function a(){} //这是函数声明,相当于定义了一个函数a,并给其分配了内存 a = 21; //此时作用域中已经存在了a变量(a函数),因此该赋值将直接赋值给作用域中的a而不是全局的a console.log('里面', a); //21,由于作用域中存在a变量了,因此直接打印作用域中的a } console.log('外面', a); //1,全局作用域中存在a变量,并赋值为1,因此打印1
JS 中有两种函数,
一种是普通函数,
function a() {}
一种是函数对象,匿名函数,函数没有名字,变量有。
var a = function() {}
“函数对象”,它实际上是声明一个匿名函数,然后将该函数的 init 方法赋值给该变量。
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(ES6,独一无二的值)。
引用数据类型:对象(Object)、数组(Array)、函数(Function)。
Undefined 这个值表示变量不含有值。
可以通过将变量的值设置为 null 来清空变量。
当您声明新变量时,可以使用关键词 "new" 来声明其类型:
“函数对象”,它实际上是声明一个匿名函数,然后将该函数的 init 方法赋值给该变量。
本类型的变量是存放在栈内存(Stack)里的
var a,b;
a = "zyj";
b = a;
console.log(a); // zyj
console.log(b); // zyj
a = "呵呵"; // 改变 a 的值,并不影响 b 的值
console.log(a); // 呵呵
console.log(b); // zyj
引用类型的值是保存在堆内存(Heap)中的对象(Object)
var a = {name:"percy"};
var b;
b = a;
a.name = "zyj";
console.log(b.name); // zyj
b.age = 22;
console.log(a.age); // 22
var c = {
name: "zyj",
age: 22
};
JavaScript 对象是拥有属性和方法的数据。JavaScript 对象是键值对的容器
对象(车),属性(奔驰),方法(启动)
javaScript对象中属性具有唯一性(这里的属性包括方法),如果有两个重复的属性,则以最后赋值为准。
如果您把值赋给尚未声明的变量,该变量将被自动作为 window 的一个属性。
非严格模式下给未声明变量赋值创建的全局变量,是全局对象的可配置属性,可以删除。
var var1 = 1; // 不可配置全局属性 var2 = 2; // 没有使用 var 声明,可配置全局属性 console.log(this.var1); // 1 console.log(window.var1); // 1 console.log(window.var2); // 2 delete var1; // false 无法删除 console.log(var1); //1 delete var2; console.log(delete var2); // true console.log(var2); // 已经删除 报错变量未定义
在使用 return 语句时,函数会停止执行并跳出,若要返回则返回指定的值。
作为参数的的变量称为形参,带入的参数称为实参。
所谓的作用域就是指某段程序文本代码。绝大多数的语言是采用静态作用域规则,js也是。
静态作用域:指声明的作用域是根据程序正文在编译时就确定的,有时也称为词法作用域
动态作用域:程序中某个变量所引用的对象是在程序运行时刻根据程序的控制流信息来确定的
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar(); // 结果是 1
"We are the so-called "Vikings" from the north." //Vikings被截断
用反斜杠 (\) 来转义 "Vikings" 字符串中的双引号
"We are the so-called \"Vikings\" from the north."
=== 为绝对相等,即数据类型与值都必须相等。
常见字符串实例方法
var x = "JohnJohn"; // x 是字符串 y = x.charAt(2); // h y = x.charCodeAt(2); // 104 y = x.concat(y, y); // JohnJohn104104, x+y+y y = x.indexOf('h'); // 2, 索引从0开始 y = x.lastIndexOf('h'); // 6 y = x.slice(); y = x.split('o'); //J,hnJ,hn y = x.substr(2); // hnJohn y = x.substring(2,4) // hn,[2,3] y = x.toLocaleLowerCase(); // johnjohn,小写 y = x.toLocaleUpperCase(); // JOHNJOHN,大写 y = x.toString(); // 转成Stirng y = x.toUpperCase(); // JOHNJOHN,大写 y = x.trim(); // JohnJohn,去除两端的空格 y = x.valueOf(); // 返回某个字符串对象的原始值
字符串会根据顺序进行结果运算
var result1=5+5+"abc"; //结果将是"10abc" var result2= ""+5+5+"abc"; //结果将是"55abc"
js基于条件进行赋值,多元表达式
p>1?p<b?p>b:p=6:p=3
p>1? 整体 :p=3
1、当 p>1 时返回 p<b?p>b:p=6
- 1.1、当 p<b 时返回 p>b
- 1.2、当 p>=b 时返回 p=6
2、当 p<=1 是返回 p=3 所以先执行 1
实例:当 p=9 的时候,返回 p<b?p>b:p=6 接着执行 1.1,当 p=9<12 时,返回 p>b,即 9>12,条件不成立所以最终结果为 false。
es6内优化if语句
const condition = 2 let obj = { '1' : () => { document.write(1) }, '2' : () => { document.write(2) }, '3' : () => { document.write(3) }, } obj[condition]()
上述需要做非处理,否则当无condition,程序报错,后续程序无法继续
switch 中 case的判断是===的判断,即数据类型和值的双重判断。
switch(n) { case 1: 执行代码块 1 break; case 2: 执行代码块 2 break; default: 与 case 1 和 case 2 不同时执行的代码 }
for...of 是 ES6 新引入的特性。它既比传统的for循环简洁,同时弥补了forEach和for-in循环的短板。
var array = new Array(); var x; array[0] = 1; array[3] = 2; array[4] = 3; array[10] = 4; for( x in array ){ alert(array[x]); // 依次显示出 1 2 3 4 } alert(array.length); // 结果是11 for( var i=0 ; i<4 ; i++){ alert(array[i]); // 依次显示出 1 undefined undefined 2 }
for...in 循环会自动跳过那些没被赋值的元素,而 for 循环则不会,它会显示出 undefined。
break 语句用于跳出循环。continue 用于跳过循环中的一个迭代。
垃圾回收(GC),它是专门释放对象内存的一个程序。
(1)在底层,后台伴随当前程序同时运行;引擎会定时自动调用垃圾回收期;
(2)总有一个对象不再被任何变量引用时,才释放。
GC的算法归根结底可以分为三类:GC标记-清除法,引用计数法,GC复制算法。
undefined 与 null 的区别:表面上 undefined 与 null 都是什么都没有的意思,但是实际上 undefined 是未定义(就是变量没有初始化),null 是一个变量初始化了,但是什么值都没给,只给了一个空对象;进一步说,undefined 与 null是值相等,类型不相等。
NaN 是一个特殊的数值,NaN 即非数值(Not a Number),这个数值用于本来要返回数值的操作数未返回数值的情况。NaN 与任何值都不相等,包括 NaN 本身。可以通过 isNaN() 方法来判断某个数值是否是NaN这个特殊的数
如果我们想测试对象是否存在,在对象还没定义时将会抛出一个错误。
if (myObj !== null && typeof myObj !== "undefined")
正确的方式是我们需要先使用 typeof 来检测对象是否已定义:
if (typeof myObj !== "undefined" && myObj !== null)
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换。
search() 方法 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。
replace() 方法 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。
exec() 方法用于检索字符串中的正则表达式的匹配。该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
try 语句测试代码块的错误。
catch 语句处理错误。
throw 语句创建自定义错误,一般用来显示异常。
finally 语句在 try 和 catch 语句之后,无论是否有触发异常,该语句都会执行。
声明提升:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部,函数提升到最顶部,然后到变量。但是初始化不会提升。
//声明提升,等于var x = 5
x = 5; // 变量 x 设置为 5 elem = document.getElementById("demo"); // 查找元素 elem.innerHTML = x; // 在元素中显示 x var x; // 声明 x
//初始化不提升
var x = 5; // 初始化 x elem = document.getElementById("demo"); // 查找元素 elem.innerHTML = x + " " + y; // 显示 x 和 y var y = 7; // 初始化 y,y为undefined
//函数提升到最顶部,所以匿名函数表达getName在后面,覆盖了函数
var getName=function(){ console.log(2); } function getName(){ console.log(1); } getName(); //结果为2
变量的声明和函数的声明提升,提升的时机发生在预解析过程中。
这里要注意,var和let都会变量提升,但是var的提升log不会报错;let的提升由于暂时性死区,未赋值的变量读取会会导致 ReferenceError 的报错
预解析过程也就是创建 AO(Activation Object) 的过程。
创建AO过程:
- 创建 AO 对象。
- 将形参和函数内变量声明作为对象的属性名,属性值统一为 undefined。
- 将实参赋值给形参。
- 找函数内的函数声明作为对象的属性名,属性值为函数体。
JavaScript 中的所有数据都是以 64 位浮点型数据(float) 来存储。所有的编程语言,包括 JavaScript,对浮点型数据的精确度都很难确定:
var x = 0.1; var y = 0.2; var z = x + y // z 的结果为 0.30000000000000004 if (z == 0.3) // 返回 false
采用整数的乘除法解决
var z = (x * 10 + y * 10) / 10; // z 的结果为 0.3
表单验证:一般放在客户端上使用HTML的require等,或者JS,减少服务器请求
服务端数据验证是在数据提交到服务器上后再验证。
客户端数据验证是在数据发送到服务器前,在浏览器上完成验证。
用 js 表单验证判断表单字段(fname)值是否存在,如果想多个表单都使用同一个函数调用,传入参数后功能会失效
function validateForm(form) { var x = form.name.value; if (x == null || x == "") { alert("输入不能为空!"); return false; } } onsubmit="return validateForm()" //有效,当验证不通过时,返回 false,可以阻止表单提交。 onsubmit="validateForm()" //验证不通过的情况下,并不能阻止表单提交。onsubmit调用方法默认返回 true
面向对象语言中 this 表示当前对象的一个引用。但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
- 1、在对象方法中, this 指向调用它所在方法的对象。
- 2、单独使用 this,它指向全局(Global)对象。
- 3、函数使用中,this 指向函数的所属者。
- 4、严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
- 5、在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素。
- 6、apply 和 call 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
var person1 = { fullName: function() { return this.firstName + " " + this.lastName; } } var person2 = { firstName:"John", lastName: "Doe", } person1.fullName.call(person2); // 返回 "John Doe"
有一个总的原则,那就是this指的是,调用函数的那个对象。如下,调用this的是myObject,返回其内容
<script> var myObject, myArray; myObject={ name: "hahaha ", hsk: "en" }; function myFunction(a, b) { alert(this); return this.name +this.hsk; } myArray = [10, 2] myObject = myFunction.apply(myObject, myArray); document.getElementById("demo").innerHTML = myObject; </script>
const 的本质: const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。使用 const 定义的对象或者数组,其实是可变的。使用Object.freeze()方法来 冻结变量 ,可彻底锁死变量。
不能对常量对象、数组重新赋值:
const cars = ["Saab", "Volvo", "BMW"]; cars = ["Toyota", "Volvo", "Audi"]; // 错误
可以修改:
// 创建常量数组 const cars = ["Saab", "Volvo", "BMW"]; // 修改元素 cars[0] = "Toyota"; // 添加元素 cars.push("Audi");
const在同一作用域内不能重新赋值
JSON 是 JS 对象的字符串表示法。它使用文本表示一个 JS 对象的信息,(JSON)本质是一个字符串。JSON(格式字符串) 和 JS 对象(也可以叫JSON对象 或 JSON 格式的对象)互转(JSON.parse 和 JSON.stringify)。
href="#"与"?"与href="javascript:void(0)"的区别
// 阻止链接跳转,URL不会有任何变化 <a href="javascript:void(0)" rel="nofollow ugc">点击此处</a> // 虽然阻止了链接跳转,但URL尾部会多个#,改变了当前URL。(# 主要用于配合 location.hash) <a href="#" rel="nofollow ugc">点击此处</a> // 同理,# 可以的话,? 也能达到阻止页面跳转的效果,但也相同的改变了URL。(? 主要用于配合 location.search) <a href="?" rel="nofollow ugc">点击此处</a> // Chrome 中即使 javascript:0; 也没变化,firefox中会变成一个字符串0 <a href="javascript:0" rel="nofollow ugc">点击此处</a>
JS的单线程多线程:
浏览器中有三个常驻的线程,分别是JS引擎,界面渲染,事件响应。由于这三个线程同时要访问DOM树,所以为了线程安全,浏览器内部需要做互斥:当JS引擎在执行代码的时候,界面渲染和事件响应两个线程是被暂停的。所以当JS出现死循环,浏览器无法响应点击,也无法更新界面。现在的浏览器的JS引擎都是单线程的,尽管多线程功能强大,但是线程同步比较复杂,并且危险,稍有不慎就会崩溃死锁。
回调函数:setInterval和setTimeout计时并不是多线程,这两个函数根本上其实是事件触发函数
- setInterval() - 间隔指定的毫秒数不停地执行指定的代码。
- setTimeout() - 在指定的毫秒数后执行指定代码。
异步Ajax:异步Ajax确实用了多线程,只是Ajax请求的Http连接部分由浏览器另外开了一个线程执行,执行完毕之后给JS引擎发送一个事件,这时候异步请求的回调代码得以执行。Http请求的执行在另外一个线程中,由于这个线程并不会操作DOM树,所以是可以保证线程安全的。发起Ajax请求和回调函数中间是没有JS执行的,所以页面不会卡死。
webworker:能够在另外一个线程中执行计算密集的JS代码而不引起页面卡死,这是真正的多线程。然而为了保证线程安全,Worker中的代码是不能访问DOM的。
ES6的Promise(Promise 只不过是一种更良好的编程风格。):Promise 构造函数只有一个参数,是一个函数,这个函数在构造之后会直接被异步运行,所以我们称之为起始函数。起始函数包含两个参数 resolve 和 reject。Promise 类有 .then() .catch() 和 .finally() 三个方法,promise更像是错误检查
异步函数:异步函数 async function 中可以使用 await 指令,await 指令后必须跟着一个 Promise,异步函数会在这个 Promise 运行中暂停,直到其运行结束再继续运行。
JS共享线程:SharedWorker的实质在于share,不同的线程可以共享一个线程,他们的数据也是共享的。
函数自调用:如果表达式后面紧跟 () ,则会自动调用。
(function () { var x = "Hello!!"; // 我将调用自己 })();
ES6 新增箭头函数
(参数1, 参数2, …, 参数N) => { 函数声明 }
(参数1, 参数2, …, 参数N) => 表达式(单一)
// 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的。箭头函数是不能提升的,所以需要在使用之前定义。
argument 对象包含了函数调用的参数数组。如找出最大数:
x = findMax(1, 123, 500, 115, 44, 88); function findMax() { var i, max = arguments[0]; if(arguments.length < 2) return max; for (i = 0; i < arguments.length; i++) { if (arguments[i] > max) { max = arguments[i]; } } return max; }
call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。两者的区别在于第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
function myFunction(a, b) { return a * b; } myObject = myFunction.call(myObject, 10, 2); // 返回 20 function myFunction(a, b) { return a * b; } myArray = [10, 2]; myObject = myFunction.apply(myObject, myArray); // 返回 20
私有变量可以用到闭包。在 JavaScript 中,所有函数都能访问它们上一层的作用域。JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。闭包就是在提供了一个在外部访问另一个函数内部局部变量的方式。
var add = (function () { var counter = 0; //只在add赋值时执行了一次 return function () { //该处对于add()return了一个函数,而不是一个数,counter共用了
return counter += 1;} })(); add(); add(); //调用了内部函数 add(); // 计数器为 3
闭包要解决的问题是:一个函数可以拥有私有变量,并且外部可以通过闭包访问该私有变量(该变量没有修饰符,所以不是全局变量),如特权方法,Java的private
闭包是实现面向对象所必须的,面向对象的基本要素是封装性
addEventListener() 方法添加的事件句柄不会覆盖已存在的事件句柄。可以向一个元素添加多个事件句柄。
element.addEventListener(event, function, useCapture);
第三个参数用于选择描述事件是冒泡还是捕获。该参数是可选的。
事件冒泡,它会从一个最具体的的元素接收,然后逐级向上传播, p=>button=>div=>body..........事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。
事件捕获与冒泡流完全相反,从最不具体的元素接收到最具体的元素接收事件 body=>div=>button=>p
HTMLCollection 是 HTML 元素的集合。NodeList 是一个文档节点的集合。
HTMLCollection 元素可以通过 name,id 或索引来获取。NodeList 只能通过索引来获取。
new 和不 new的区别:
- 如果 new 了函数内的 this 会指向当前这个 person 并且就算函数内部不 return 也会返回一个对象。
- 如果不 new 的话函数内的 this 指向的是 window。
function person(firstname,lastname,age,eyecolor) { this.firstname=firstname; this.lastname=lastname; this.age=age; this.eyecolor=eyecolor; return [this.firstname,this.lastname,this.age,this.eyecolor,this] } var myFather=new person("John","Doe",50,"blue"); var myMother=person("Sally","Rally",48,"green"); console.log(myFather) // this 输出一个 person 对象 console.log(myMother) // this 输出 window 对象
prototype 继承:一个已存在构造器的对象中是不能直接添加新的属性,使用 prototype 属性就可以给对象的构造函数添加新的属性:
function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; } Person.prototype.nationality = "English";
var myFather = new Person("John", "Doe", 50, "blue");
myFather.nationality; //English
构造函数名.prototype.新属性或者新方法
字符串使用 indexOf() 来定位字符串中某一个指定的字符首次出现的位置,字符串使用 indexOf() 来定位字符串中某一个指定的字符首次出现的位置
- 1. indexOf('a', 5) 查找的是字符串前5位之后的第一个a
- 2. lastIndexOf('a', 7) 查找的是字符串前7位之内的最后一个a
浏览器对象模型(Browser Object Model (BOM)),主要用于客户端浏览器的管理,对浏览器window的操控
history.go() 这个方法来实现向前1,刷新0,后退-1的功能。
js警告alert(),确认confire(),提示prompt()
Cookie 是一些数据, 存储于你电脑上的文本文件中。当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。Cookie 的作用就是用于解决 "如何记录客户端的用户信息":
- 当用户访问 web 页面时,他的名字可以记录在 cookie 中。
- 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。
当浏览器从服务器上请求 web 页面时, 属于该页面的 cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。
主要的 jQuery 函数是 $() 函数(jQuery 函数)。如果您向该函数传递 DOM 对象,它会返回 jQuery 对象,带有向其添加的 jQuery 功能。
//传统JS function myFunction() { var obj=document.getElementById("h01"); obj.innerHTML="Hello jQuery"; } onload=myFunction; //引入JQ function myFunction() { $("#h01").html("Hello jQuery"); } $(document).ready(myFunction);
黑马pink:
1、浏览器:渲染引擎和JS引擎:逐行解释
2、JS:
ES(ECMAScript)
DOM(Document Object Model):通过DOM提供的借口可以对页面上的各种元素进行操作(大小、位置、颜色等)
BOM(Browser Object Model):提供独立与内容的、可以和浏览器窗口进行互动的对象结构(弹出框、浏览器跳转、获取窗口分辨率)
3、程序调试常用输入输出:alert(msg)、console.log(msg)、prompt(info)
4、JS为弱类型或者说动态语言,可以不用提前声明变量,程序运行时自动确定
5、HTML标签属性使用的为双引号,所以JS内推荐使用单引号
6、未定义undefined+1为Nan,空值null+1为1
7、字符转换toString()和String()(该方法为强制)显示转换,18+"为隐式转换,更推荐;
数字转换parseInt()、parseFloat()(如parseInt('12px'),可转为12,若为px12,则nan,需以数字开头)和Number()(强制)和隐式转换'12'-0( - * /)
boolean转换,空、否定如''、0、NaN、null、undefined全为false,其余为true
8、逻辑短路:逻辑运算与、或、非时,按从左到右运算,若左边表达式即可确定结果,则右边不执行
比如逻辑与:
表达式1 && 表达式2
第一个为真,返回表达式2 (123 && 456) => 456 第一个是真了,就看你第二个是不是真了,是真就返回真,不是就返回假值如0、''、null
第一个为假,返回表达式1 (0 && 456) => 0 第一个就不是真了,就没必要看第二个了,直接返回
逻辑或相反
9、三元表达与if类似,作为判断,比if简略
10、switch判断为全等===判断;判断执行后如果没有break,则往下继续执行且不进行判断,后续都执行,直到找到break
11、循环里注意使用continue和break
12、js创建数组:
var arr = new Arrry(); var arr = ['1','2'];
13、js内函数形参和实参不需要完全匹配:实参多于形参,多出的部分忽略;实参少于形参,未实例化参数undefined
14、return只能返回一个值,可以把多个值放于数组内
15、函数内用于检测实参内容的argument是伪数组,有length、按照索引存储、没有真正数组的方法,如pop();
16、函数内部(不包含if、for等块级)没有声明就赋值的变量是全局变量,声明了如var的为局部变量
在函数内的定义
function fun{ var a=b=c=9 //改声明实则 var a = 9, b=9,c = 9. bc 为全局,若要多变量声明应该为逗号分割 var a=9 ,b = 9 , c= 9 }
17、js预解析: 函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部,函数提升到最顶部,然后到变量提升(包含匿名函数)。但是初始化不会提升。
18、对象: 属性和方法;构造函数
function Obj(uname, age){ this.name = uname this.age = age
this.ability = function(run){
console.log(run)
} } var chen = new Obj('jj', 18); // 先new一个空对象,this指向空对象, 添加属性和方法,然后给chen返回对象 //chen.name = 'jj';
chen.ability(7.1s);
对象遍历用 for...in 循环
19、js内置对象: mdn查询文档: 常用的Math、Date、数组操作Array、字符串操作String
Math:内置静态对象,不需要new;绝对值、最大值、上下取正等
Date:需要new,一般考虑使用具有唯一性的时间戳。= +new Date():参数为空返回当前时间差,若填写参数,返回参数时间差,该参数尽量使用字符串型,数字型问题较多
数组:instanceof / isArray检测是否为数组、push / unshift追加元素、pop / shift删除,删除元素不可添加参数、reverse反转、sort排序(只用sort只能对个位数排序,即如果没有指明 compareFunction
,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序):sort(function(a,b){ return a-b; })将比较函数compareFunction当参数传入进行升序排列、indexOf / lastIndexOf数组索引;toString / join转换成一行字符串;concat连接数组返回新数组,等同于+;slice(a,b)数组截取;splice(起点,个数)删除内容;charAt(index)根据位置返回字符; charCodeAt(index)根据位置返回ascii;
对数组进行增删改时,由于增和删只能在前后,所以考虑新建数组,将新内容放到新数组,入去重的时候,利用判断新数组内是否有相同值来进行去重。
字符串:基本包装类型:String Number Boolean
js将简单数据类型包装成复杂类型,所以var str = ‘jj’ 才会有属性如length可操作
var str = 'jj'; str.length var temp = new String('jj'); var str = temp; temp = null;
字符串不可变,开辟新地址,少重新赋值,少拼接:若重新定向值str = 'cjj'; 指针指向值cjj新地址,老地址不释放,所以尽量不重新赋值字符串
substr(索引号,长度)截取字符串;slice(a,b)数组截取,b取不到;replace(被替换的字符,替换的字符)只会换第一个字符;split('分隔符')字符转数组;toUppeCase() / toLowerCase()转大小写
19、JS数据类型:简单数据类型,也叫基本数据类型或者值类型,null,string,number等,放在栈里;复杂数据类型也叫引用类型,如数组,函数,放在堆里,但是堆地址放在栈内,指向堆,如函数参数实参和形参指向同一地址,一个变,另一个也变。JS没有堆栈,这里说堆栈是为了更好理解
20、立即执行函数
(function ( ){ }) ( ) / (function ( ){ } ( ) )
(function(a){ //形参 console.log(a) //打印1 })(1) //实参
21、回调函数
回调函数原理∶函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。所以一般回调函数是写在执行函数的最后,如果有定时器之类的,写在定时器之后
function a(callback) { timer = setInterval(function () { clearInterval(timer); // 回调函数写到定时器结束里面 // if (callback) { // // 调用函数 // callback(); // } callback && callback(); } ) console.log(2); //最后输出2 1 } a(function () { console.log(1); })