【JS】基础学习

consoe.dir()可以显示一个对象所有的属性和方法

变量

变量声明var a;,赋值a = 10;

变量命名规则和规范

前端缩进是两个空格。
变量命名规则:
①第一个字符必须是字母、下划线_或美元符$
②其它字符可以是字母、下划线、美元符或数字
③不能使用关键字和保留字
变量命名规范:
①多个单词使用驼峰标识,例如:var lastName; var userLoginFlag;
②尽量做到见名知意,不要使用拼音
③赋值=、+=(或其他符号)两边都加上一个空格
④一条语句结束,后面跟一个;,函数、循环、if后面不需要加分号

基本语法

值类型——数据类型

  • 不可改变的原始值(栈数据:像裤兜装东西的环节,先进后出)
    Number、Boolean、String、undefined、null、Symbol
  • 引用值(堆数据)
    array、object、function
var arr = [1, 2];
var arr1 = arr; //arr里的东西放到arr1里,arr和arr1同时指向一个房间
arr = [1, 3]; //arr等于一个新的东西,此时arr等于1,3,arr1等于1,2
document.write(arr1); //1,2

原始值没有属性和方法!

字符串插值(模板字面量最常用的一个特性是支持字符串插值${})

/****变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。****/
let value = 5;
​​​​let exponent = 'second';
let age = 18;
​​​​// 以前,字符串插值是这样实现的:
​​​​let interpolatedString =
​​​​  value + ' to the ' + exponent + ' power is ' + (value * value);
​​​​// 现在,可以用模板字面量这样实现:
​​​​let interpolatedTemplateLiteral =
​​​​  `${ value } to the ${ exponent } power is ${ value * value }, i am ${age + 1} years old`;
​​​​console.log(interpolatedString);   // 5 to the second power is 25
​​​​console.log(interpolatedTemplateLiteral);   // 5 to the second power is 25​​, i am 19 years old

/****字符串中调用函数****/
function f(){
  return "have fun!";
}
let string2= `Game start,${f()}`;
console.log(string2);  // Game start,have fun!

判断数据类型

  • typeof六种数据类型:number、string、boolean、undefined、object、function
  • typeof两种写法:typeof(num)、typeof num
typeof(null); //object
typeof(a); //'undefined'是字符串类型的undefined

被认定为false的值

  • undefined,null,NaN,“”,0,false

delete

delete操作符用于删除对象的某个属性, 返回值是布尔(delelte删除不了变量, 删除不了原型链中的变量 )
不使用任何声明创建变量,它会被视作全局变量,挂载到window对象上面,等价于delete window.age,所以删除成功

基础运算符

  • “+”
    1.数字运算、字符串链接
    2.任何数据类型加字符串都等于字符串
var a = "a" + 1; //a1
var a = "a" + 1 + 1; //a11
var a = 1 + 1 + "a" + (1 + 2); //2a3
  • “-”,“*”,“/”,“%”,“=”,“()”
    除了+号,其他的运算符两边有字符串的都会转为数字类型
  • 优先级“=”最弱,“()”的优先级较高
  • “++”,“- -”,“+=”,“-=”,“/=”,“*=”,“%=”
//赋值的顺序自右向左,计算的顺序自左向右
var a = 10;
var b = ++a - 1 + a++; //b=11-1+11=21
document.write(b + " " + a); //21 12

a++;  -->  a = a + 1; //自身+1再赋值给自身
a += 10  -->  a = a + 10;
  • a++和++a。通常用在数字变量上面。
    如果直接使用a++++a是没有区别的。如果参与运算时有以下区别:
    var a = 100;
    a++ + 10; //110先使用,之后自身再+1
    ++a + 10; //111 先自身+1,之后再使用
var a = 1;
document.write(a++); //1; 打印a++的结果,这是一个执行语句,++在后面识别的语法是先运行执行语句,执行完了最后再++,在等document打印完了之后再++,所以打印的还是1。
document.write(a); //2; 这里打印的才是++完的结果。

var a = 1;
document.write(++a); //2; ++在前面优于一切,a先++,a是1++1就等于2,然后再执行++完的打印语句结果
document.write(a); //2;

比较运算符

  • “>”,“<”,“==”,“>=”,“<=”,“!=”(比较结果为boolean)

全等:

  • “==”在判断两个值时会自动进行类型转换。"123" == 123; //true
  • “===”表示全等,需要类型和数据完全相等,在判断两个值时不会自动进行类型转换。"123" === 123; //false

全不等:

  • !==表示全不等,也不会自动进行类型转换。"123" != 123; //false"123" !== 123; //true

逻辑运算符

“&&”,“||”,“!”(运算结果为布尔类型)

  • &&:与(同时为真)。当结果是真的就会往后走,直到返回最后那个真的,一旦有假的就返回那个假的。false && true; //false
  • ||:或(一个为真)。当结果是真的就直接返回真的,后面的就不看了,碰到假的就会往后看,一直寻找真的;两个都是假的就返回最后那个假的。false || true; //true
  • !:非(取反)。!false; //true

显示类型转换

其他类型转成数字类型:

  • Number()
  • parseInt(string,radix)将字符串转成整数,radix参数可以不写是进制的意思
  • parseFloat(string)将字符串转成小数
    如果第一个字符是数字或运算符号就开始解析,直到遇到非数字字符,停止解析并得到解析结果;如果第一个字符是非数字或非运算符号,则不解析并得到结果NaN

其他类型转成字符串类型:

  • 变量.toString() 只针对数字类型和布尔类型,null和undefined会报错
  • String(变量) 所有类型都可以
  • + 其他的数据类型和字符串通过+运算符进行拼接时,会自动转成字符串

其他类型转成布尔类型:

  • Boolean()
    如果某个值为“”(空字符串)、0(包括0、-0)、undefined、NaN、null时,转换成布尔类型的值为false,否则除了那5个值其他的都为true

隐式类型转换

  • ++ 或 - -
  • +或-
  • isNaN()
  • 加号运算符(+)
  • -*/%
  • && || !
  • < > <= >=
  • == !=

条件语句

  • if、if else、if else if else(值的范围判断)
    三元运算符(if else的简写):表达式1 ? 表达式2 : 表达式3
var age = 20;
var result = age >= 18 ? "成年人": "未成年";
  • switch case(值的相等判断,使用全等运算符===)
    break(结束整个循环)
    continue(终止本次循环,进行下次循环)
var holidayName = prompt("请输入节日");
switch (holidayName){
    case "情人节":
        alert("买玫瑰看电影");
        break; //不加这个会case穿透,会执行下面的语句
    case "平安夜":
        alert("买苹果吃大餐");
        break;
    case "生日会":
        alert("买蛋糕");
        break;
    default:
        alert("上班");
}

循环遍历

  • while
while(循环条件){
	//循环体
}
//打印0-99的数字
var i = 0;
while(i<100){
	console.log(i)
	i++
}
  • do while
    特点:不管条件成不成立,do循环体都会先执行一次
do{
	//循环体
} while(循环条件)
  • for
//语法
for(初始化表达式1; 条件表达式2; 自增/减表达式3){
	//循环体4
}
//语句一:通常会写成var i = 1;
//语句二:进行条件判断
//语句三:i++或i--
//练习一:打印100~1的数字
for(var i=100; i>0; i--){
	console.log(i);
}

//练习二:计算0-100奇数的和
var oddTotal = 0;
var evenTotal = 0;
for(var i=0; i<100; i++){
	//取余数为0就是偶数,否则就是奇数
	if( i % 2 === 0 ){
		evenTotal += i;
	}else{
		oddTotal += i;
	}
}
console.log(evenTotal)
console.log(oddTotal)

//练习三:正三角爱心(第一行一个,第二行二个...)
for(var i=0; i<6; i++){ 
    //循环里面每行❤的个数,不+1第一行的❤就是0个,也可以写成j<=i;
    for (var j=0; j<i+1; j++){ 
        document.write("❤ ");
    }
    document.write("<br />"); //每行结尾处换行
}

//练习四:九九乘法表
//初始化值都从1开始
for (var i = 1; i < 10; i++){
    for ( var j = 1; j <= i; j++){
        var str = j + "*" + i + "=" +  j * i + "&emsp;"
        document.write(str)
    }
    document.write("<br />");
}

断点调试debug

  • 方式一:打开浏览器的F12→Sources→点击源代码的行数→单步调试
  • 方式二:在代码中写上debugger;

数组

  • 数组属性
    ①length属性:获取数组的长度
    ②索引值也称下标值index,数组的索引值从0开始的
  • 数组遍历
    访问数组的最后一个元素:nums.length - 1;
//正向遍历
var nums = [100, 30, 68, 96, 26, 128, 9];
for(var i = 0; i < nums.length; i++){
	console.log(i);//打印索引值
	console.log(nums[i]);//打印数组内容
}

//反向遍历
//通过nums.length-1先获取最后一个元素
for(var i = nums.length-1; i >= 0; i--){
	console.log(i);//打印索引值
	console.log(nums[i]);//打印数组内容
}

//练习一:数组中元素拼接,所有的元素使用-进行分割100-30-68-96-26-128-9
var msg = ""; //要有初始化值,没有赋值就会是”undefined“
for(var i = 0; i < nums.length; i++){
    //1.先把所有的数组内容拼接到msg中
 	msg += nums[i];//100306896261289
	
	//2.用-分割
	//方法一:除了最后一个元素(不等于最后一个),其他的都加“-”
	if( i !== nums.length - 1 ){
		msg += "-"
	}
	
	//方法二:如果是最后一个元素,用break跳出循环
	/*if( i === nums.length - 1 ){
		break;
	}
	msg += "-";*/
	
	//方法三:先遍历前面3个元素都加上-,最后单独拼接最后一个元素
}
console.log(msg);

//练习二:求数组的和和平均值
var total = 0; //要有初始化值,没有赋值就会是undefined
for(var i = 0; i < nums.length; i++){
	console.log(nums[i]);//确保可以获取每个数字
	total += nums[i]
}
console.log(total);//和:457
var avarage = total / nums.length;
console.log(avarage);//平均值:68.29

//练习三:求数组中的最大值
/*1.定义一个变量,变量保存第一个数字
	2.遍历所有的数字
	3.将所有遍历的数字和保存的第一个数字进行比较
      如果 遍历的数字 > 保存的第一个数字
      就将遍历的数字放到保存的变量中*/
var max = nums[0];
for (var i = 0; i < nums.length; i++){
    console.log(nums[i]); //打印遍历的数字
    if (nums[i] > max){
        max = nums[i];
    }
}
console.log("最大值"+max); //128

//练习四:数组的反转操作
/*死办法*/
var temp = nums[0]; //定义一个临时变量,取出数组中第一个数字保存给临时变量
nums[0] = nums[nums.length-1]; //把数组中最后一个数字赋值给数组中第一个数字
nums[nums.length-1] = temp; //把临时变量保存的数字赋值给数组中最后一个数字
console.log(nums);

var temp = nums[1];
nums[1] = nums[nums.length-2];
nums[nums.length-2] = temp;
console.log(nums);

var temp = nums[2];
nums[2] = nums[nums.length-3];
nums[nums.length-3] = temp;
console.log(nums);

var temp = nums[3];
nums[3] = nums[nums.length-4];
nums[nums.length-4] = temp;
console.log(nums);

/*循环写法*/
//只需要遍历到数组中间进行交换
for (var i = 0; i < nums.length / 2; i++ ){
    var temp = nums[i];
    nums[i] = nums[nums.length-1-i];
    nums[nums.length-1-i] = temp;
}
console.log(nums)

//练习五:冒泡排序
//实现思路:相邻的两个两个进行比较,第一项与第二项比较,谁大就放后面,然后再第二项与第三项比较,谁大就放后面,一直比较直到把最大的值放在最后面,完成第一轮排序;再比较前面的数字,比较出倒数第二大的数字放在倒数第二的位置完成第二轮排序,以此类推。

函数

函数其实就是对某段代码的封装,完成某一个功能。
使用步骤:定义函数,调用函数。

  • 组成形式
    ①函数名称(小驼峰)
    ②参数(形参实参)
    ③返回值
    使用return关键字来返回结果,可以把值返回到函数外
    一旦在函数中执行return操作,那么当前函数会停止
    如果函数中没有使用return语句,那么函数有默认的返回值:undefined
    如果函数使用return语句,但是return后面没有任何值,那么函数的返回值也是:undefined

定义函数的方式

①函数声明写法

function 函数名() {
}

②函数表达式写法

var test = function abc() {
	document.write('a');
}
test();
//这个叫函数表达式;=号后面的是表达式,会忽略后面abc的名字,执行函数是test(),不写abc的名字就是匿名函数表达式
//1.function
const aaa = function() {}

//2.对象字面量中定义函数,以下两种方式是一样的
const obj = {
    bbb: function() {},  //ES5写法
    bbb() {}  //ES6函数的增强写法
}

//3.es6中的箭头函数
const ccc = (参数列表) => {} //可以有多个参数列表,只有一个参数时小括号可省略
const sum = (num1, num2) => num1 + num2 //函数代码块中只有一行代码,return和方括号可省略
//练习一:加法计算器
function sum(sum1, sum2){
    return sum1 + sum2;
}
var result1 = sum(10, 20);
console.log(result1); //10+20=30

//练习二:计算矩形的面积:宽度*高度
function calcRectArea(width, height){
    return width * height;
}
var result2 = calcRectArea(10, 20);
console.log(result2);//10*20=200

//练习三:计算圆型的面积:πr²
function calcCircleArea(radius){
    return Math.PI * radius * radius;
}
var result3 = calcCircleArea(10);
console.log(result3);

//练习四:计算1~n数字的和
function calcNSum(n){
    var total = 0;
    for (var i = 1; i <= n; i++){
        //console.log(i); //打印1~n的值
        total += i;
    }
    return total;
}
var result4 = calcNSum(5);
console.log(result4);

//练习五:数组的反转操作(如果有多个数组可以调用一个函数)
function reverseArray(arr){
    for (var i = 0; i < arr.length / 2; i++ ){
        var temp = arr[i];
        arr[i] = arr[arr.length-1-i];
        arr[arr.length-1-i] = temp;
    }
    return arr;
}

var nums1 = [100, 30, 68, 96, 26, 128, 9];
nums1 = reverseArray(nums1);
console.log(nums1);

var nums2 = [116, 3, 90, 68, 96, 26, 128, 19];
nums2 = reverseArray(nums2);
console.log(nums2);

//练习六:选择排序
//实现思路:可以选择最大的或最小的。选择最小的直接放在第一个,先把第一项与第二项进行比较,谁小谁放在第一个,再把第一项与第三项进行比较,谁小谁放在第一个,再把第一项与第四项进行比较,谁小谁放在第一个,以此类推,找出最小的值放在第一个完成第一轮排序;再用第二项与第三项比较,第二项与第四项比较,找出第二小的值放在第二个完成第二轮排序,以此类推。
function sortArray(arr){
  /***死办法***/
  //第一步:先找出数组中最小的值放在第一个位置
	for(var i = 1; i < arr.length; i++){
		//第一项的值和所有的值进行比较,如果第一项比后面的值大,第一项arr[0]就和arr[i]做交换(把arr[i]中最小的值的交换到第一个位置)
		if(arr[0] > arr[i]){
			var temp = arr[0];
			arr[0] = arr[i];
			arr[i] = temp;
		}
	}
  //第二步:找出数组中第二小的值放在第二个位置
	for(var i = 2; i < arr.length; i++){
		//第二项的值和所有的值进行比较,如果第二项比后面的值大,第二项arr[1]就和arr[i]做交换
		if(arr[1] > arr[i]){
			var temp = arr[1];
			arr[1] = arr[i];
			arr[i] = temp;
		}
	}
	//第三步:找出数组中第三小的值放在第三个位置
	for(var i = 3; i < arr.length; i++){
		//第三项的值和所有的值进行比较,如果第三项比后面的值大,第三项arr[2]就和arr[i]做交换
		if(arr[2] > arr[i]){
			var temp = arr[2];
			arr[2] = arr[i];
			arr[i] = temp;
		}
	}
	//。。。类推

  /***循环写法***/
  for(var j = 0; j < arr.length; j++){
  	for(var i = j+1; i < arr.length; i++){
			if(arr[j] > arr[i]){
				var temp = arr[j];
				arr[j] = arr[i];
				arr[i] = temp;
			}
		}
	}
}
var nums1 = [100, 30, 68, 96, 26, 128, 9]; //定义一个需要排序的数组
sortArray(num1); //调用函数并传入nums1数组
console.log(nums1) //打印nums1排序后的结果

立即执行函数

全称:立即调用函数表达式(针对初始化功能的函数)
此类函数没有声明,在一次执行过后即释放。
作用:会创建一个独立的执行上下文环境,可以避免外界访问或修改内部的变量,也避免了对内部变量的修改。

(function (){
}()) //可以有参数和返回值
//只有函数表达式才能被符号执行
var test = function(){
	console.log("a")
}()

什么是回调函数

当一个函数做另一个函数的参数时,这个函数就叫回调函数。

函数的参数——arguments(实参列表)

1.arguments对象是所有(非箭头)函数中都可用的局部变量
2.如果调用者传入的参数多于函数接受的参数,可以通过arguments去获取所有的参数
3.arguments对象和function是分不开的,只有函数开始时才可用

//定义一个函数,计算所有参数的和
function sum(){
    var total = 0;
    for (var i = 0; i < arguments.length; i++){
        total += arguments[i];
    }
    return total;
}
console.log(sum(10, 20, 30));
console.log(sum(10, 20, 30, 40, 50));

变量的作用域

在js(ES5之前)没有块级作用域的概念,但是函数可以定义自己的作用域。
局部变量:定义在函数内部的变量。
全局变量:定义在script标签中的变量。

预编译前奏

①函数声明整体提升function test() {} //test()在最前面也能访问函数里面的内容
②变量声明提升var a;

  • imply global暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有。a = 123; --> window.a = 123;var a = b = 123; --> window.a = 123; --> window.b = 123;
  • 一切声明的全局变量,全是window的属性(window就是全局)。var a = 123; ---> window.a = 123
function test() {
  var a = b = 10;
  console.log(window.a)//undefined
  console.log(window.b)//10;b没经声明就赋值,此变量为全局对象所有,归GO。
}
test();

console.log(b)//undefined,只有函数声明才会提升,var b走的是变量是函数表达式
var b = function () {
}

预编译四部曲

预编译发生在函数执行的前一刻,编译完四步之后执行函数(走函数体里面的代码,如果里面有函数声明就不会再次执行了,因为在变量的时候已经被提升了)
函数的预编译:
①创建AO对象(Activation Object 执行期上下文)
②找形参和变量声明(var a),将变量和形参名作为AO的属性名,值为undefined
③将实参值和形参统一(将实参放到形参里)
④在函数体里面找函数声明,值赋予函数体
然后再执行函数,AO发生在函数执行的前一刻
全局的预编译:
①创建GO对象
②找变量声明(var a),将变量作为GO的属性名,值为undefined
③找函数声明,值赋予函数体
然后再执行函数
规律:一旦有重名的,有a变量和a函数,在执行第一条就访问a的话就一定是函数
注意:AO执行的是函数内部,函数外面的是全局GO
注意:如果AO里的c=100;没有用var声明,就会给全局的GO
注意:GO就是window
注意:如果AO和GO都有test同名的属性,AO和GO会形成链式关系,AO有就用自己的,没有就往上面的GO找;如果AO的if语句判断的a为undefined,那么if语句就不会执行,不会向外层找a。
注意:if语句里面不能有函数声明

作用域精讲

  • [[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了执行期上下文的集合。
  • 作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫作用域链。
  • 运行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁。
  • 查找变量:从作用域链的顶端依次向下查找。

内存管理

js会在定义变量时为我们分配内存

  • js对于基本数据类型内存的分配会在执行时,直接在栈空间进行分配
  • js对于复杂数据类型内存的分配会在堆内存中开辟一块空间,并将这块空间的指针返回值变量引用

闭包

函数可以作为另外一个函数的参数,也可以作为另外一个函数的返回值来使用

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏

闭包的作用

  • 实现公有变量。(函数累加器)
  • 可以做缓存。(eater)
  • 可以实现封装,属性私有化。(Person())
  • 模块化开发,防治污染全局变量。

对象

对象中的方法:属性值是函数管这样的属性叫方法(其实就是函数),对象的方法调用是对象名.属性方法()var obj = { name: '哈哈'; eat: function (){} },调用obj.eat()
注意:对象里面写属性是用冒号,对象外面增加属性是用等号。

  • 属性的增删改查
    增加:对象名.属性名=‘值’
    删除:delete对象名.属性名
  • 创建方法:
    1、对象字面量:var obj = {}
    2、构造函数来构造对象:
    第一种是系统自带的构造函数,前面加个new+构造函数的执行,可以返回一个对象,返回是通过return返回,所以需要拿一个变量来接受var obj = new Object()
    第二种是自定义构造函数,function Person(){}这是一个构造函数,如果想通过自定义的构造函数构造对象的话,需要通过new操作符,var obj = new Person()就可以生成对象,多次调用这个构造函数方法并且有自己的属性可以通过传递参数,调用多次构造方法可以产生独一无二的对象。
    注意:由于构造函数和正常函数的写法没有任何区别,所以构造函数需要使用大驼峰式命名规则TheFirstName
function Student(name, age){
	this.name = name;
	this.age = age;
	this.grade = 2015
}
var s1 = new Student('xixi', 18);
var s2 = new Student('haha', 20);

构造函数内部原理:
①在函数体最前面隐式的加上this:{}
②执行this.xxxx = xxxx;
③隐式的返回this。
注意:new构造函数会隐式return返回this

包装类:原始值没有属性和方法!原始值给它赋属性和方法会调用包装类,然后会删除这个包装类再返回undefined。

注意:有两个函数和两个函数调用,只会执行后面的那个函数和函数调用

3、Object.create(原型)

原型

定义:原型是function对象的一个属性,它定义了构造函数制造出来的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
利用原型特点和概念,可以提取共有的属性。
对象如何查看原型:隐式属性__proto__
对象如何查看对象的构造函数:constructor

原型链

所有对象最终都会继承自Object.prototype

this指向

前端面试之彻底搞懂this指向

定时器

setTimeOut:该定时器n秒后触发一次函数,只会执行一次。
setInterVal:该定时器n秒执行一次函数,循环多次执行。

js怎么绑定原生事件

①DOM元素绑定事件<button onclick="demo()">按钮3</button>,function demo(){}
②JS里绑定事件,在事件名称前面加上一个on修饰test.onclick=()=>{}
③绑定事件监听test.addEventListener("click",()=>{})

js的三大事件

鼠标事件、键盘事件、html事件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值