JS进阶知识设计到很多底层原理 是JS技术栈必须要掌握的知识,面试中尝尝问到这些知识,考验对JS的更深层次的理解,想要深入学习 这块必须得掌握
文章目录
前言
JS进阶知识的几块知识点都是非常重要的,学习JS必须得掌握这块才能更深层次的理解这门语言。本文先来介绍了一些 JavaScript 常用的基础知识点,打好基础知识点的底子,以作后面进阶学习的抛砖引玉之用。
目录
一、语句分号问题
<title></title>
</head>
<!--
js一条语句的后面可以不加分号
是否加分号是编码风格问题, 没有应该不应该,只有你自己喜欢不喜欢
在下面2种情况下不加分号会有问题
1\小括号开头的前一条语句
2\中方括号开头的前一条语句
**解决办法: 在行首加分号
情形一: 小括号开头的前一条语句___IIFE 匿名函数自调用时 需要在函数开头小括号下面加上一个分号
var a = 3
;(function () {
})
不加分号的错误理解: 将3看成是函数调用
var a = 3(function () {
})
情形二: 中方括号开头的前一条语句
var b = a
;[1, 3, 5].forEach(function (item) {
console.log(item)
})
不加分号的错误理解:
var b = a[5].forEach(function(e){//a[5]是undefined
console.log(e)
})
-->
<body>
<script type="text/javascript">
var a = 3
console.log(a)
;(function(){
})()
//后面跟个匿名函数就需要在开头加括号
var b = 4
;[1,3].forEach(function(){
})
</script>
二、两种数据类型及数据类型的判断(*)
这里对于引用数据类型的数据类型判断非常之重要! 几种方法一定要掌握! 这里也是最早认识原型链的地方。 obj instance of 其实就是判断该对象的原型是否在原型链上。
<title>数据类型</title>
</head>
<body>
<!--
1、分类 *基本类型 1、string 任意字符串 number任意数字 boolean(true/false) 2、undefined null
*对象(引用)类型 *object 任意对象
*function 特别的对象——特别在可以执行
*Array 特别的对象(有数值下标索引,内部数据有序)
2、判断:*typeof typeof 返回数据类型的 字符串表达
*instanceof 判断对象的具体类型 函数/数组
* ===
-->
<script>
//1、基本数据类型的判断。
var a ;
console.log(a,typeof a);//undefined ,"undefined"
console.log(undefined === 'undefined');//false ===要求两边的值和数据类型完全相同
console.log((typeof a === 'undefined' , a === undefined));//true 两个都可以判断出一个值是否是undefined类型
a=4;
console.log(typeof a ==='number');//只有这一种方法判断数值类型 不能用 === 因为数值可以改变 不像undefined只有一个值;
a = '#bfa';
console.log(typeof a === 'string');//注意这些都是小写 没有大写 string _true String -false
a = true ;
console.log(typeof a === 'boolean');
a = null ;
console.log(typeof a);//给出object 相当于一个啥也没有的空对象 不能用 ==='null' 来判断
console.log(a === null);//可以用这个来判断null 因为null和undefined 都只有一个值 。 返回true;
//2、对象
var b1 = {
b2:[1,'abc',console.log],
b3: function(){
console.log('b3');
return function(){
return '返回这个';
}
}
};
console.log('分割线——————————————————————————————————')
console.log(b1 instanceof Object);//b1是不是Object 类型的实例。 b1是个函数 函数也是对象 所以是Object
console.log(b1 instanceof Array);//b1不是数组 返回false;
console.log(b1.b2 instanceof Array , b1.b2 instanceof Object); //b2既是数组 也是对象 返回两个true;
console.log(b1.b3 instanceof Function , b1.b3 instanceof Object); //b3既是函数 也是对象 返回两个true;
console.log('分割————————————————————————————————————')
console.log(typeof b1.b3 == 'function');//true 返回了function字符串。
console.log(typeof b1.b2[2] == 'function');//true consolo.log 也是一个 方法/函数 。
//故而可以像下面这样输出数字100
b1.b2[2](100);//即 b1.b2[2] === console.log 完全等价于一个函数;
console.log(b1.b3()());
console.log("分割线————————————————————————————————————")
console.log(typeof b1.b3);
console.log(typeof b1.b2);//typeof 一个函数时给出function 而array时给出Object;
/*综上 typeof 可以判断出 undefined number Boolean function
不可判断 null与Object array与Object
instanceof _用以判断对象的具体类型
=== 可以判断 undefined 和 null;
*/
console.log("___________________________")
console.log(typeof 123)
console.log(typeof typeof 123)
console.log(typeof typeof typeof 123)
console.log(typeof '123')
console.log(typeof typeof '123')
console.log(typeof typeof typeof '123')
</script>
做一点补充:
<script type="text/javascript">
//1、 undefined和null的区别是?
var a ;
console.log(a);//未定义 返回undefined;
a = null ;
console.log(a);//赋值null 虽然是空值 但是有定义
//2、什么时候需要给变量赋值null;(object)——初始赋值 表名对象 结束赋值 回收垃圾对象
var obj = {name:'TOM',age:12};
var obj2 = null ;//初始赋值为null 表明定义了一个空对象 将要进行赋值。
obj2 = ['fxxk',13];
//进行一波操作的最后
obj2 = null ;//将上面的数组占有的内存空间释放 网页会删除掉没有指向的垃圾对象。
//3、严格区分变量类型和数据类型?
/*数据的类型: *基本类型 *对象类型
变量的类型: *基本类型 保存的就是基本类型的数据 *引用类型 保存的是栈内存中的地址值 变量类型就是变量里存储的值的类型
*/
var c = function(){
};
console.log(typeof c);//返回function 是因为 c的地址指向了function
</script>
三、数据 变量 与内存
<title></title>
</head>
<body>
<!--
1、什么是数据?
*它存储在内存中代表特定信息的符号、载体。 本质上是01010101
特点 可传递 可运算 内存中操作的目标——数据 算数运算 逻辑运算 赋值 运行函数
2、什么是内存?
*内存条通电之后产生的可存储数据的临时空间。断电就么的了;
*内存产生和死亡:内存条(电路板) ==>通电 ==> 产生内存空间 ==>存储数据 ==> 处理数据 ==>断电内存空间和数据都消失。
*一块小内存的2个数据 内部存放的数据+地址数据。
3、什么是变量?
*可变化的量 ——变量名 + 变量值 每个变量都对应着一块小内存 变量名用以指向对应的那块内存。
内存的分类 栈 ——全局变量 局部变量 堆 对象。 函数等 ——但是注意函数名/标识对象的变量名的栈空间里 作为指针。
4、三者之间的关系?
*内存是用来存储数据的临时空间。
*变量用来标识内存
-->
<script type="text/javascript">
var age = 18 ;
console.log(age);//先通过age找到内存 再读取内存取出数据——变量值。
var obj1 = {name:'mmmm'};
console.log(obj1);//读取的是地址 地址指向堆内存中的存放的数据。注意只有对象数据类型访问的地址 其他直接访问值。
//小问题1:var a = xxx; a中到底保存的是什么?
//* xxx是基本数据类型 则 a中保存的就是这个数据 *xxx是一个对象 a中保存的是这个对象的地址值
// 是*一个变量 将xxx的内存内容传递过来 两者都可能;
var a = 3;
a = function(){
};//a中地址值;
var b = 'abc';
a= b ;//a中字符串abc
b= {};
a = b ;//a中地址值
//小问题2;关于引用变量赋值的问题
//2、两个引用变量指向同一个对象 ——两个变量存的地址值是同一个对象的
var obj1 = {name:'tom'};
var obj2 = obj1 ;
console.log('_____________________________');
//注意:JS中的操作全都是按值操作的 只不过针对对象时 这个值是指向对象堆内存的地址值;
obj1.name = 'jack';
console.log(obj2.name);
function fn (obj){
obj.name = 'bob';
}
fn(obj1);
console.log(obj2.name);
var a = {age:12};
var b = a;//此时b指向age这个对象
a = {name:'bob'};
console.log(b.age,b.name);//b的地址没有指向新的a对象 所以不含name属性 12/undefined
//3、小问题:JS中调用函数时传递变量参数时 始终是按值传递的。(基本值/地址值)
//
var c = 3;
function fn (c){
c = c + 1;
}
fn(c);
console.log(c);//输出3 函数只是传入3这个数值 可以返回一个4 但是并没对c这个变量值进行任何操作。
function fn2 (obj){
console.log(obj.name);
};
var obj2 = {name:'TOM'};
fn2(obj2);//此时输出一个TOM;
//4、问题 JS引擎如何管理内存
/*1、内存生命周期: *分配小内存空间,得到他的使用权 *存储数据 可以反复进行操作 *释放当前小内存空间
2、释放内存
*局部变量:函数执行完自动释放 *对象:当对象成为垃圾对象后 被垃圾回收器回收。
*/
var a = 3;
var obj = {};//占用三个空间 a obj的地址栈内存 obj对象堆内存
obj = null ;//函数执行时 内部的局部变量存在 函数结束后 内部的局部变量会自动释放。
//函数中申请的一个变量 栈内存保存的地址马上自动释放 指向的堆内存中的对象在后面某个时刻被垃圾回收器回收
</script>
四、对象 与 函数 ;
对象:
<title></title>
</head>
<!--
1、什么是对象?
*多个数据的封装体 用来保存多个数据的容器。
*一个对象代表现实中的一个事物
2、为什么要用对象?
统一管理多个数据。
3、对象的组成?
属性:属性名 + 属性值 (所有的属性名都是字符串 所以语法上优化了 不用写'name' 'age' 属性值可以是任意类型
和 方法: 方法是一种特别的属性 属性值是函数的属性 即为方法。
4、如何访问对象内部的数据?
* .属性名 ——.是访问符
* ['属性名']
-->
<body>
<script type="text/javascript">
var obj1 = {
name:'TOM',//对象里的属性
age:12,//对象里的属性
setName:function(name){//对象里的方法
this.name = name;
},
setAge: function(age){//对象里的方法
this.age = age ;
}
};
obj1.setName('MMLS');
console.log(obj1.name);
obj1['setAge'](28);
console.log(obj1['age']);//两种访问方法 还是 .xxx更简单
//什么i情况下必须使用 ['属性名'] 的访问方式呢?
var p = {};
//给P添加与i个 content-type属性
//p.content-type = 'text -json'; 会报错 因为属性名中包含特殊的符号 和.冲突 这种情况下必须用[] 不会报错。
var propName = 'myAge';
var value = 18;
//p.propName = value ; 不能用
p[propName] = value ;
console.log(p[propName]);//即属性名不确定的情况下必须得用 ['属性名'];
</script>
函数:
<title></title>
<!--
1.什么是函数?
*实现特定功能的n条语句的封装体 *只有函数是可以执行德瓦,其他类型的数据都不能执行。
2.为什么要用函数?
提高代码的复用能力。
*便于阅读和交流
3.如何定义函数?
函数声明
表达式
匿名函数
4.
*test():直接调用
*obj.test() 通过对象调用
* new test () new申明调用
*test.call /apply (obj) 相当于 obj.test 临时的让test方法成为obj的方法进行调用 可能obj里没有这个方法
当对象里没有某个方法时 不能用.test调用 可以用apply call来临时调用函数作为方法。
-->
</head>
<body>
<script type="text/javascript">
function showInfo (age){//第一种 函数声明方式
if(age < 18){
console.log('未成年');
} else if (age >= 60){
console.log('太大');
}else{
console.log('刚好');
}
}
showInfo(18);
showInfo(61);
var fn2 = function(){//第二种 表达式声明。 (还有第三种匿名函数申明)
console.log('fn2()');
}
</script>
回调函数(*)
<title></title>
<!--
1.什么函数才是回调函数?
*你自定义的 + 你没有调用 + 最终还是执行 的函数 = 回调函数。
2.常见的回调函数?
*dom事件回调函数
*定时器回调函数
*ajax请求回调函数(后面讲
*生命周期回调函数(后面讲
-->
</head>
<body>
<button type="button" id="btn1">测试点击事件</button>
<script type="text/javascript">
document.getElementById('btn1').onclick = function(){//dom事件回调函数
alert(this.innerHTML);
}
//定时器
//超时定时器setTimeout
//循环定时器
setTimeout( function(){//定时器回调函数
alert('到点了');
},2000)
</script>
匿名函数自调用:
<title></title>
</head>
<!--
1*全称——immediately-invoked function expression 立即执行函数表达式
2*作用(优势)
*隐藏实现:函数内部表达式外面看不见
*不会污染外部的全局命名空间
-->
<body>
<script type="text/javascript">
(function(){//匿名函数并直接自调用 括号括起来 再加上括号
var a = 2;
console.log(a+3);
})();
// console.log(a);//执行后这行代码报错 a is not defined 因为他访问不到匿名函数内部。
(function(){
var a = 1;
function test (){
console.log(++a);
}
window.$ = function(){//向外暴露一个全局函数。
return {
test:test
}
}
})()
$().test();
</script>
函数中的this:
<title></title>
<!--
1、this? 是什么?
*所有函数都有一个this
*它的值是调用函数的当前对象;
*(任何函数本质上都是通过某个对象来调用的);window最大
2、如何确定this的值?
-->
</head>
<body>
<script type="text/javascript">
function Person (color){
console.log(this);//这里输出一个window ——语句一
this.color = color ;
this.getColor = function(){
// console.log(this); //语句二
return this.color;
};
this.setColor = function (color){
// console.log(this); //语句三
this.color = color;
};
}
Person("red");//this 是谁? 输出一个window 同样是由console语句一输出的
var p = new Person("yellow");//this是谁 ? 输出一个person this指的是person对象、
p.getColor();//this 是 p
var obj = {};
p.setColor.call(obj,"black");//这里 this 是 obj;
var test = p.setColor;
test();//this是? 是window 因为是直接调用的这个函数
function fun1(){
function fun2(){
console.log(this);
}
fun2();//this指的是window
}
fun1();//
</script>
上面这些函数知识将在下一文章 JS函数高阶知识做详细阐述 此处只简单介绍
总结
本文简单介绍了一下 变量 内存 对象 和 函数的一些基础
这里这是为高级知识学习打下基础 难点还在后面。 但是基础的掌握往往也是至关重要的。