func();//建议:调用函数必须写在函数表达式的下面,这次以举例为例说明原因
var func = function (){
console.log('张小凡');
}
代码报错的原因是相当于执行了以下代码,声明一个变量没有赋值,又调用了这个变量+();是肯定报错的。代码如下。
var func;
func();
func = function (){
console.log('张小凡');
}
案例3
经过上面两个案例说明应该了解了变量提升和函数提升,现在将两者柔和一起来试试看~~~
var num = 10;
fun();
function fun(){
console.log(num);
var num = 20;
}
观察上面代码,根据步骤一步一步来,知道浏览器解释器是怎么执行这段代码的。
var num;
function fun(){ //函数内部也是要执行预解析的
var num; //因为就近原则,不会去找全局作用域里面声明的num = 10;所以undefined
console.log(num);
num = 20;
}
num = 10;
fun();
案例4
在用案例巩固一下~~ ,加深自己是意识。请看下面代码
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
思考一下,代码会以什么顺序执行呢,请看下面~~~
function f1() {
var a;
a = b = c = 9;
// var a = b = c = 9; 相当于 var a = 9; b = 9; c = 9; b和c 直接赋值 没有var声明 当全局变量看
// 集体声明 var a =9,b = 9,c = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a); //属于局部变量, 报错
调用了f1();函数,又console.log()三个数,本来能输出六个数字,但因为最后一个 console.log(a);中的a属于局部变量,访问不了所以报错信息里面提示 a is not defined 原因找到。
2.JS作用域
2.1 定义
JavaScript作用域:就是代码名字(变量) 在某个范围内起作用和效果 目的:提高程序的可靠性以及减少命名冲突。
2.2 作用域分类
全局作用域:整个script标签或者是一个单独的js文件
局部作用域:(函数作用域)在函数内部就是局部作用域 只在函数内起作用和效果。
2.3 变量作用域(根据作用域的不同将变量分为全局变量和局部变量)
全局变量:在全局作用域下的变量,在全局下都可以使用; 如果在函数内部,没有声明直接赋值的变量也属于全局变量。
局部变量:在函数作用域下的变量,函数的形参也可以看做是局部变量
从执行效率上看两者的区别:
全局变量只有在浏览器关闭的时候才会销毁,比较占内存资源;局部变量当我们程序执行完毕就会销毁,比较节约内存资源。
2.4 作用域链
内部函数访问外部函数的变量,采用的是链式查找的方式决定哪个值 这种结构我们称为作用域链 使用的是就近原则。
function fun1 () {//外部函数
var num = 1;
function fun2 () {//内部函数
console.log(num);
}
fun2();
}
var num = 2;
fun1();
显而易见,由就近原则可知,结果为 1,接下来再看一段代码~~~
var a = 1;
function fn1 () {
var a = 2;
var b = '22';
fn2();
function fn2 () {
var a = 3;
fn3();
function fn3 () {
var a = 4;
console.log(a); // a的值?
console.log(b); // b的值?
}
}
}
fn1();
采用就近原则很快得到答案,看看和你猜的一不一样~
3. 对象
谈到对象,就要涉及了许多方面的内容了,知识量有点大,现在平静一下~,耐心的看下去。
3.1 定义
在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。简而言之:对象是由属性和方法组成。目的:使JS中的对象表达结构更清晰,更强大。
属性:事物的特征,在对象中用属性来表示
方法:事物的行为,在对象中用方法来表示
3.2 创建对象的三种方式
3.2.1 利用字面量创建对象
注意点:1.属性和方法采取键值对的方式 键 属性名;值 属性值 2.多个属性和方法中间逗号隔开 3.方法冒号跟的是一个匿名函数
// var obj = {}; 创建了一个空的对象
var obj = {
name: '张小凡', //属性区
age: '18',
sex: '男',
say: function () {
console.log('hello world');
}
}
// 调用对象属性的方法1:采取对象名.属性名
console.log(obj.name);
// 调用对象属性的方法2:采取对象名['属性名']
console.log(obj['age']);
// 调用对象的方法 say 对象名.方法名()
obj.say();
3.2.2 利用 new Object 创建对象
注意点:采用等号赋值方法 添加对象的属性和方法、每个属性和方法之间用 分号结束
var obj = new Object();
obj.name = '张小凡'; //追加属性
obj.age = 18;
obj.sex = '男';
obj.say = function () { //追加方法
console.log('hello world');
}
3.2.3 构造函数创建对象
注意点:1.构造函数泛指某一大类 类似于 Java 语言里卖弄的 类 2.特点:把对象里面一些相同的属性和方法抽取出来封装(封装的不是普通代码而是对象)到函数里面,这样避免了很多的属性和方法的大量重复
//构造函数的语法格式
//this总是指向函数的直接调用者(而非间接调用者); 如果有new关键字,this指向new出来的那个对象
function 构造函数名 () {
this.属性 = 值;
this.方法 = function () { }
}
new 构造函数名();
案例:
function Family (name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.doing = function(result){
console.log(result);
}
}
var boy = new Family('张小凡',18,'男');
console.log(boy.name);
console.log(boy['sex']);
boy.result('我在打游戏~')
var girl = new Family('张晓樊',18,'女');
console.log(girl.name);
console.log(girl.sex);
girl.result('我在追剧~')
细节:1、构造函数首字母要大写、构造函数不需要return就可以返回结果、调用构造函数必须使用 new、只要使用new 构造函数名 就相当于创建了一个对象。2、我们利用构造函数创建对象的过程我们称为对象的实例化。3、new 构造函数可以在内存中创建一个空的对象 函数里面的this都会指向这个空对象,执行构造函数里面的代码 给这个空对象添加对象和方法并返回这个新对象
3.3 遍历对象
简言之:for in 遍历我们的对象。
// 格式
for(变量 in 对象){
}
案例:
// 案例
var obj = {
name:'张小凡',
age:18,
sex:'男'
}
for(var key in obj){ //for in 里面的变量我们喜欢写 k 或者 key
console.log(key); //i 变量输出 得到的是 属性名
console.log(obj[key]); //obj[i]得到的是属性值
}
3.4 内置对象
定义:指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常见的或是最基本而必要的功能。内置对象的最大优点就是帮助我们快速开发 JS提供多个内置对象:Math、Date等
3.4.1 Math是数学对象 不是一个构造函数,所以我们不需要new来调用 而是直接使用里面的属性和方法即可。
console.log(Math.PI); //一个属性 圆周率
console.log(Math.max(1,45,42)); //45
console.log(Math.max(1,'张小凡')); //NaN
console.log(Math.max()); // -Infinity 负的无穷大
利用对象封装自己的数学对象
var myMath = {
PI:3.141592653,
max:function(){
var max = arguments[0];
for(var i = 1;i < arguments.length;i++){
if(arguments[i]>max){
max = arguments[i];
}
}
return max;
},
min:function(){
var min = arguments[0];
for(var i = 1;i < arguments.length;i++){
if(arguments[i]<min){
min = arguments[i];
}
}
return min;
},
}
console.log(myMath.PI);
console.log(myMath.max(1,5,8));
console.log(myMath.min(1,5,8));
3.4.2 绝对值方法
console.log(Math.abs(1)); //1
console.log(Math.abs(-1)); //1
console.log(Math.abs('1')); // 隐式转换 会把字符串型 -1 转换为数字型 1
console.log(Math.abs('张小凡')); //NaN
3.4.3 三个取整方法
// (1) Math.floor() 地板 向下取整 往最小取值
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.9)); // 1
// (1) Math.ceil() 天花板 向上取整 往最大取值
console.log(Math.ceil(1.1)); // 2
console.log(Math.ceil(1.9)); // 2
// (1) Math.round() 四舍五入 .5特殊往大去取
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.5)); // 2
console.log(Math.round(-1.5)); // -1
3.4.4 Math对象随机数方法 random() 返回一个随机的小数 [0,1) 范围左闭右开 这个方法里面不跟参数。
console.log(Math.random());
### JavaScript
* js的基本类型有哪些?引用类型有哪些?null和undefined的区别。
* 如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)
* Object是引用类型嘛?引用类型和基本类型有什么区别?哪个是存在堆哪一个是存在栈上面的?
* JS常见的dom操作api
* 解释一下事件冒泡和事件捕获
* 事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何组织默认事件?
* 对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?
* this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?
* call,apply,bind
* 显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链
* 创建对象的多种方式
* 实现继承的多种方式和优缺点
* new 一个对象具体做了什么
* 手写Ajax,XMLHttpRequest
* 变量提升
* 举例说明一个匿名函数的典型用例
* 指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?
* attribute和property的区别
* document load和document DOMContentLoaded两个事件的区别
* JS代码调试
* **[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
![](https://img-blog.csdnimg.cn/img_convert/a69e7b92af546ecaedf148f129bfef2b.png)