(分别从内存,赋值,函数传参的角度描述)
答: 1)、内存的角度: 基本类型在内存中,占据一块空间,空间里存储的就是值,所以也叫,值类型。获取值是属于直接获取 引用类型在内存中,占据两块空间,第一块存储的是地址,第二块存储的是值。也叫地址类型。获取数据是属于间接取值。 2)、赋值: 基本类型:赋的就是值 引用类型:赋的就是地址 3)、函数传参:(等价于把实参赋值给形参) 基本类型:传的是值 引用类型:传的是地址
4)、
基本类型有:Undefined、Null、Boolean、Number、String、Symbol,还有:Bigint,
引用类型有:统称为 Object 类型。
5)、可以写应用场景:
number:表示数字,如:年龄,成绩,金额,等会做加减乘除,比较大小等数学运算的数据
string:非数字信息的描述
boolean:表示是否(两种情况)
Symbol:表示唯一性时
引用类型:表示复杂的数据时,即:一个数据中包括了若干个信息时。
都是数据类型,隐式转换为boolean类型时都是false。
1)、undefined:是JavaScript的数据类型,表示定义变量后,没有赋值,表示值的缺失 2)、null:对象没有引用的值,即就是:引用类型里没有存储地址。Null还可以用来清除堆区的标记,防止内存泄漏。表示对象的缺失
代码示例:
1) undefined: ? var a; ? //JavaScript中定义一个变量,没有赋值时,默认为undefined console.log(typeof a); // undefined console.log(b); // 报错,因为b没有定义。所有,在浏览器的控制台中会报 b is not defined ? 2) ?null: ? var person = null;//定义了一个引用类型,没有指向。 console.log(person); //输出null。 console.log(typeof person);//输出object,person的数据类型是Object,值是null ?
1)、typeof undefined 的结果是undefined
2)、typeof null 的结果是object,所以,它个对象有关系。表示对象的缺失。
1)、undefined:
变量声明且没有赋值
获取对象中不存在的属性
函数需要实参,但是调用时没有传值,形参是undefined
函数调用没有返回值或者return后没有数据,接受函数返回值的变量
2)、null:
对象不存在就是null
手动设置变量的值或某一个属性值为 null
JS 获取 DOM 元素,如果没有获取到指定的元素对象,返回 null
正则捕获时,如果没有捕获到,返回 null
Object.prototype.proto 的值是 null
document 和 body 很多属性都是 null
02JavaScript面试系列_undefined和null变量类型的理解_分别定义null类型变量和undefined类型变量,并使用alert()函数继续输出-CSDN博客
都是用来判断两个数据是否相等。
===(恒等) 1、如果类型不同,就[不相等] 2、如果两个都是数值,并且是同一个值,那么[相等]。 3、如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等] 4、如果两个值都是true,或者都是false,那么[相等]。 5、如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。 6、如果两个值都是null,或者都是undefined,那么[相等]。
==(等同) :
1、如果两个值的类型相同,则按照===的思路进行比较
2、如果两个值的类型不同,先做隐式转换,把两个数据转换成同种类型,再进行判断。所以,给大家的感觉是不判断类型。
隐式转换规则:
? ? ? ? ```js
a、如果一个是null、一个是undefined,那么[相等]。 b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。 c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。 d、任何其他组合,都[不相等]。 ```
答: js在预编译阶段,会对声明进行提升,如:声明变量(var),声明函数(function 函数名(){}) 1)、用声明的方式定义变量或者函数,会有提升 2)、声明的变量和函数会提升当前作用域的最顶端。 3)、变量声明,只提升声明不提升赋值;
答: 相同点:
这三个关键字都是用来定义变量的 不同点: 1)、var定义的变量会声明提升,let和const定义变量不会声明提升 2)、var定义的变量作用域是全局作用域和函数(局部)作用域,let和const是块级作用域(所在花括号) 3)、var定义的全局变量是window对象的属性,let和const定义的全局变量不是window的属性 4)、var可以定义多个同名的变量,let和const不行 5)、let有暂时性死区 6)、let在循环里,可以暂存循环变量。 7)、const定义的变量是只读的。const修饰的是直接指向(修饰)的内存。
JavaScript面试题,let和var的区别,let和const是什么意思?_let可以定义全局吗-CSDN博客
JavaScript面试题,let和const是什么意思?_在js中let和const是做什么的-CSDN博客
不会报错,const修饰的是数组,而不是数组的元素。
补充:const修饰引用类型时,都修饰的是地址。而不是数据。
<script type="text/javascript"> //const修饰的变量是只读,不能修改的,即是常量 //const修饰的是直接指向(修饰)的内存 function testf1(){ //1、const修饰的变量是只读,不能修改的,即是常量 //const temp1 = 100;//定义了一个变量temp1,赋值为100,const表示以后不能再修改了 //temp1 = 200;//这句话会报错,不能给只读变量赋值(Assignment to constant variable.) //2、const修饰的是直接指向(修饰)的内存 const arr = [12,23,34];//引用类型在内存中是两块区域,const修饰的是arr(arr是在栈区) arr[0]=100;//修改的是堆区的内存 console.log(arr); arr = [1,2,3];//这句话要报错,因为,这句话像改变arr(栈区)的地址 } window.onload = function(){ testf1(); } </script>
作用域:,就是变量起作用的区域(范围)。或者说,js代码执行时,查找变量的范围。
作用域链::当js编译器在寻找变量时,先在最近的作用域(花括号)里找,如果找不到,则朝上一级作用域(花括号)里找,依次类推,直到找到或者找不到为止。这就是作用域链。
详细请阅读:原生js面试题:作用域和作用域链,let声明的全局变量不是window对象的属性_有四个作用域(scope),分别是global(全局)、script(脚本)、local(局部)、b-CSDN博客
答:事件流就是事件的流向。事件流分为三个阶段:捕获阶段,事件源,冒泡阶段。
https://blog.csdn.net/jiang7701037/article/details/81481550
利用dom事件的冒泡,完成,把dom元素的事件由父元素进行处理。即:在父元素进行事件绑定,完成子元素想要完成的功能。并在父元素的事件处理函数里,使用事件对象的target来判断是否为子元素触发事件。
减少了代码量
让动态添加的子元素也会具有事件的功能。即:子元素的dom操作,不会影响事件绑定。
假设一个ul标签里有5个li,请使用事件委托的方式完成,点击每个li,显示每个li里的内容
Ul.onclick = function(event){ ? ?Let e = event ||window.event; ? ?if(e.target.tagName.toLowerCase()==”li”){ ? Console.log(e.target.innerHTML); ? } }
1、是什么?
this是函数的内置对象。this是代名词。this代表谁,需要看场景(上下文),在js中函数就是this的场景。所以,this一般都是出现在函数内部(其实这个本质是作用域)。
2、this的几种情况(静态的描述) 以下情况所说的函数是非箭头函数。
1)、当this所在函数是事件处理函数时,this表示事件源。
2)、当this所在函数是构造函数时,this表示new出来的对象。
3)、当this所在函数是实例(对象)的方法时,this表示调用该方法的对象。
4)、当this所在函数是全局声明的函数时,
4.1)、非严格模式下:this表示window。(其实这个点和第三点一样)。因为,全局函数都是window对象的方法
4.2)、严格模式下:this是undefined。
5)、this在script标签里,表示window。
3、真正的this,需要看调用(深深的知道就行,面试时,可以不用回答这个)如:。
1)、call,apply,bind是可以改变this指向的。
2)、所谓的构造函数,我也可以不用new调用把。
3)、所谓的全局函数,我也可以把它赋给事件属性。
4、箭头函数是没有this的。
既就是:在判断this指向时,不要把箭头函数当函数看待。
一般人我不告诉他:箭头函数在编译的原理里是词法分析域
三个函数都会改变this的指向(调用这三个函数的函数内部的this)
1)、bind会产生新的函数,(把对象和函数绑定死后,产生新的函数),新的函数的所有调用都会是绑定的this。
2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。
3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。
? <body> ? ?<!-- <input type="button" value="测试" οnclick="testf()" ?/> --> </body> ? <script type="text/javascript"> ? ?//demo07面试题:请问bind,call,apply的区别 ? ?//1、相同点: ? ?// ? 三个函数都会改变this的指向(调用这三个函数的函数内部的this) ? ? ? ?//2、不同点: ? ?// 1)、bind会产生新的函数,(把对象和函数绑定死后,产生新的函数) ? ?// 2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。 ? ?// 3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。 ? ? ?//示例代码: ? ?var p1 = { ? ? ? ?name:"隔壁老王", ? } ? ? ?function eat(str,drinkstr) { ? ? ? ?console.log(this.name+"在吃"+str+",同时在喝"+drinkstr); ? } ? ? ?//1、bind: ? ?let f1 = eat.bind(p1);//f1是个函数。即,用bind把eat函数和p1对象绑死,产生新的函数叫作f1 ? ?f1("油条","豆浆");//调用f1,就相当于 p1.eat();,内部的this就是p1,永远都是p1,不会是window ? ? ?//2、call: ? ?eat.call(p1,"油泼面","面汤");//不会产生新的函数,只是临时把eat函数和p1对象绑定一下。 ? ? ?//3、apply:(与call的意思一样,只是第二个参数是数组,是原函数eat的参数) ? ?eat.apply(p1,["油泼面","面汤"]);//不会产生新的函数,只是临时把eat函数和p1对象绑定一下。 ? </script>
1)、函数名的首字母大写
2)、构造函数的调用,是用new运算符。
3)、构造函数内部,在预编译时,还会增加 var this = new Object();
4)、构造函数(看上去)没有返回值,但是,其实是有的。即:虽然程序员没有写返回值,预编译时,会增加返回值
预编译时,会增加一句:return this。
1、立刻在堆内存中申请空间,这个空间就是新的对象的内存空间
2、将新建的对象设置为函数中的this
3、逐个执行函数中的代码
4、将新建的对象作为返回值 return this
1、原型:
1)、每个构造函数(类)都会有一个原型属性(prototype)。
2)、原型属性的目的:
让所有实例共享属性和方法,共享的是构造函数(类)的原型属性(prototype)上的属性和方法。因此,节约了内存。实例是通过 __proto__
属性找到构造函数(类)的prototype属性的。
3)、原型属性里还有一个constructor属性,指向构造函数(类)本身。
2、原型链
当使用对象访问属性或者方法时,先从对象本身的内存中寻找,如果找不到,就去 __proto__
(原型)指向的内存中(类的prototype)寻找,如果找不到,则在类的原型的 __proto__
(父类的prototype)寻找,以此类推,一直找到Object,如果没有找到,则显示出错(如: *** is not defined)。
这种一直沿着属性 __proto__
朝上寻找,就是原型链的寻找。也就是原型链的意思。