js高级基础部分
基于尚硅谷的尚硅谷JavaScript高级教程提供笔记撰写,加入一些个人理解
数据类型的分类和判断
主要问题
分类
基本(值)类型
- Number ----- 任意数值 -------- typeof
- String ----- 任意字符串 ------ typeof
- Boolean ---- true/false ----- typeof
- undefined --- undefined ----- typeof/===
- null -------- null ---------- ===
对象(引用)类型
- Object --任意对象--- typeof/instanceof
- Array ---特别的对象类型(下标/内部数据有序)--- instanceof
- Function --特别的对象类型(可执行)-- typeo
数据类型判断
typeof:
typeof返回值是数据类型的字符串表达
例如:
var a = 3
console.log(typeof a==='number');//输出true
可以区别: 数值, 字符串, 布尔值, undefined, function
不能区别: null与对象, 一般对象与数组
typeof判断null为object
instanceof
专门用来判断对象数据的类型: Object, Array与Function
===
可以判断: undefined和null
简单来说,===只能判断出只有一个值的数据类型
相关问题
undefined与null的区别?
undefined代表定义了但没有赋值
null代表赋值了, 只是值为null
// 1. undefined与null的区别?
var a
console.log(a);//undefinde
a = null
console.log(a);//null
什么时候给变量赋值为null呢?
变量将指向一个对象, 但对象此时还没有确定
让变量指向的对象成为垃圾对象
// 2. 什么时候给变量赋值为null呢?
//初始
var b = null//初始赋值为null,表明将要赋值为对象
//中间
b = ['atguigu', 12]//确定对象就赋值
//结束
b = null// 让b指向的对象成为垃圾对象(被垃圾回收器回收)
严格区别变量类型与数据类型?(平常不会严格区分)
js的变量本身是没有类型的, 变量的类型实际上是变量内存中数据的类型
变量类型:(变量内存值的类型)
基本类型: 保存基本类型数据的变量
引用类型: 保存对象地址值的变量
数据类型:
基本类型
对象类型
数据,变量, 内存的理解
主要问题
什么是数据?
在内存中可读的, 可传递,可运算的保存了特定信息的'东东',本质就是0101二进制
一切皆数据, 函数也是数据
在内存中的所有操作的目标: 数据
算术运算
逻辑运算
赋值
调用函数传参
什么是变量?
- 值可以变化的量, 由变量名与变量值组成
- 一个变量对应一块小内存, 变量名用来查找到内存, 变量值就是内存中保存的内容
什么是内存?
内存条通电后产生的存储空间(临时的)
产生和死亡: 内存条(集成电路板)>通电>产生一定容量的存储空间>存储各种数据>断电==>内存全部消失
内存的空间是临时的, 而硬盘的空间是持久的
一块内存包含2个方面的数据
- 内部存储的数据(一般数据/地址数据)
- 内存地址值
内存空间的分类
- 栈空间: 全局变量和局部变量
- 堆空间: 对象
内存,数据, 变量三者之间的关系
- 内存是容器, 用来存储不同数据
- 变量是内存的标识, 通过变量我们可以操作(读/写)内存中的数据
相关问题
赋值与内存的问题
问题: var a = xxx, a内存中到底保存的是什么?
var a = 3 // 保存3
a = function () {
}//保存地址值
var b = 'abc'
a = b // b保存的数据'abc'
b = []
a = b // b保存的地址值
xxx是一个基本数据,保存的就是这个数据
xxx是一个对象,保存的是对象的地址值
xxx是一个变量,保存的是xxx的内存内容(可能是基本数据,也可能是地址值)
关于引用变量赋值问题
- n个引用变量指向同一个对象, 通过一个引用变量修改对象内部数据, 其他所有引用变量也看得见
var obj1 = { name: 'Tom' }
var obj2 = obj1
obj2.age = 12
console.log(obj1.age);//12
function fn(obj) {
obj.name = 'Bob'
}
fn(obj1)
console.log(obj2.name);//Bob
- 2个引用变量指向同一个对象,让一个引用变量指向另一个对象, 另一个引用变量还是指向原来的对象
var a = { age: 12 }
var b = a
a = { name: 'Jack', age: 13 }
console.log(b.age, a.name, a.age);//12 Jack 13
/*
这里记住一点,是将实参a赋值给形参obj,即 obj=a,此时他们指向同一对象。执行obj={age:15},obj指向发生改变,而a指向未发生改变
*/
function fn2(obj) {
obj = { age: 15 }
}
fn2(a)
console.log(a.age);//13
在js调用函数时传递变量参数时, 是值传递还是引用传递
对这个问题可以有着两种理解,第一种是理解为两个都是值传递,只是这个值可以是基本数据,也可以是地址数据。第二种则是把传递的地址值看作是引用传递,不过一般来说都当做是值传递。
var a = 3
function fn(a) {
a = a + 1
}
fn(a)// 传的不是a,而是3这个值
console.log(a);// 3
/*
执行到:fn(a);先读到a是3,把a的值传给形参a,形参a去加1,输出为4。
实参a还是实参a,所以最后输出a仍然是3。这里是基本值传递。
*/
function fn2(obj) {
console.log(obj.name);
}
var obj = { name: 'Tom' }
fn2(obj)
/*
执行到:fn2(obj);把obj中的内容(不是把{name:‘tom’}传递给形参obj,
是把obj的地址值传给形参obj,只是地址值指向的是 {name:‘tom’})传递给形参obj。
这里是地址值传递。
*/
JS引擎如何管理内存
- 内存生命周期
- 分配需要的内存空间,得到使用权
- 存储数据,可以反复操作
- 释放当前的内存空间
- 释放内存
为执行函数分配的栈空间内存(局部变量): 函数执行完自动释放
存储对象的堆空间内存(对象): 当内存没有引用指向时, 对象成为垃圾对象, 垃圾回收器后面就会回收释放此内存
var a = 3
var obj = {}// 执行到这里,一共开辟了3个内存空间
obj = null // obj指向的对象内存空间被释放,obj不释放,手动释放
function fn() {
var b = {} // 只有函数被执行的时候才会开辟内存空间,即 fn()调用
}
fn()
/*
fn()执行完,b被自动释放,b所指向的对象在后面的某个时刻由垃圾回收器回收
*/
对象的理解和使用
主要问题
什么是对象
- 代表现实中的某个事物, 是该事物在编程中的抽象
- 多个数据的集合体(封装体)
- 用于保存多个数据的容器
为什么要用对象?
便于对多个数据进行统一管理
对象的组成
属性
- 代表现实事物的状态数据
- 由属性名和属性值组成
- 属性名都是字符串类型, 属性值是任意类型
属性的分类
- 一般属性 : 属性值不是function 描述对象的状态
- 方法 : 属性值为function的属性 描述对象的行为
特别的对象
- 数组: 属性名是0,1,2,3之类的索引
- 函数: 可以执行的
如何操作内部属性(方法)
- obj.属性名
- obj['属性名'] 一般不用,但通用
相关问题
什么时候必须使用['属性名']的方式?
- 属性名不是合法的标识名(包含特殊字符:- 空格等)
- 属性名不确定
// 创建对象
var p = {}
/*情形一: 属性名不是合法的标识名*/
/*需求: 添加一个属性: content-type: text/json */
p.content-type = 'text/json' //不正确
p['content-type'] = 'text/json'
/*情形二: 属性名不确定*/
var prop = 'xxx' // 我们想让这个值(xxx)做属性名
var value = 123
p.prop = value //不正确 这么写的属性名是prop
p[prop] = value
console.log(p['content-type'], p[prop])
函数的理解和使用
主要问题
什么是函数?
- 具有实现特定功能的n条语句的封装体
- 只有函数是可执行的, 其它类型的数据是不可执行的
- 函数也是对象
为什么要用函数?
- 提高复用性
- 便于阅读交流
如何定义函数?
- 函数声明
- 表达式
fn1()// 输出fn1
fn2()// 输出undefined
//函数声明
function fn1() {
console.log('fn1');
}
//表达式
var fn2 = function () {
console.log('fn2');
}
区别:js中的变量提升
- 函数声明可以在声明前调用
- 表达式不能在声明前调用,输出为undefined
如何调用(执行)函数?
- test():直接调用
- new test():new调用
- obj.test():对象调用
- test.call/apply(obj):临时让test成为obj的方法进行调用
var obj = {}
function test2() {
this.xxx = 'atguigu'
}
test2.call(obj) // 可以让一个函数成为指定任意对象的方法进行调用
//test2.apply(obj)
console.log(obj.xxx) // atguigu
这里我的想法是,call和apply改变了函数test2中的this指向,将函数test2中的this指向从window改变,指向call和apply传入的对象(后面有讲到this的指向问题)
函数也是对象
- instanceof Object===true
- 函数有属性: prototype
- 函数有方法: call()/apply()
- 可以添加新的属性/方法
函数的3种不同角色
- 一般函数 : 直接调用
- 构造函数 : 通过new调用
- 对象 : 通过.调用内部的属性/方法
回调函数的理解
- 什么函数才是回调函数?
- 你定义的
- 你没有调用
- 但它最终执行了(在一定条件下或某个时刻)
- 常用的回调函数
- dom事件回调函数
- 定时器回调函数
- ajax请求回调函数(后面讲解)
- 生命周期回调函数(后面讲解)
匿名函数自调用:
(function (i) {
var a = 4
function fn() {
console.log('fn ', i+a)// 7
}
fn()
})(3)
- 专业术语为: IIFE (Immediately Invoked Function Expression) 立即调用函数表达式
作用
- 隐藏内部实现
- 不污染外部命名空间
- 编码js模块
this是什么?
- 任何函数本质上都是通过某个对象来调用的,没有直接指定就是window
- 所有函数内部都有一个变量this
- 它的值是调用函数的当前对象
如何确定this的值?
- test():window
- obj.test():obj
- new test():新建的对象
- test.call(obj):obj
前置知识:
本质上任何函数在执行时都是通过某个对象调用的
function Person(color) {
console.log(this)
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
var p = new Person("yello"); //this是谁? p
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();
补充
分号问题
js一条语句的后面可以不加分号
是否加分号是编码风格问题, 没有应该不应该,只有你自己喜欢不喜欢
在下面2种情况下不加分号会有问题
小括号开头的前一条语句
中方括号开头的前一条语句
解决办法: 在行首加分号
// 情形一: 小括号开头的前一条语句
var a = 3
;(function () {
})()
/*
错误理解: 将3看成是函数调用
var a = 3(function () {
})
*/
// 情形二: 中方括号开头的前一条语句
var b = 4
;[1, 3, 5].forEach(function (item) {
console.log(item)
})
/*
错误理解:
b= 4[5].forEach(function(e){
console.log(e)
})*/
- 强有力的例子: vue.js库
- 知乎热议
js高级基础部分的更多相关文章
- node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法
1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...
- JS高级前端开发群加群说明及如何晋级
JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明: 一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
- JavaScript--我发现,原来你是这样的JS(基础概念--灵魂篇,一起来学js吧)
介绍 这是红宝书(JavaScript高级程序设计 3版)的读书笔记第三篇(灵魂篇介绍),有着剩下的第三章的知识内容,当然其中还有我个人的理解.红宝书这本书可以说是难啃的,要看完不容易,挺厚的,要看懂 ...
- 微信小程序高级基础
微信小程序高级基础 微信小程序的注册和服务器配置: 小程序是什么呢?小程序是一种不需要下载安装就可以使用的应用,它实现了应用"触手可及"的梦想,用户扫一扫或者搜一下就可以打开应用, ...
- JS高级前端开发群加群说明
JS高级前端开发群加群说明 *一.文章背景: *二. 高级群: *三. 加入方式: *四. 说明: 一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在"前端开发"关键字搜 ...
- js高级之函数高级部分
基于尚硅谷的尚硅谷JavaScript高级教程提供笔记撰写,加入一些个人理解 github源码 博客下载 原型与原型链 prototype : 显式原型属性,它默认指向一个Object空对象(即称为: ...
- 前端进阶试题css(来自js高级前端开发---豪情)既然被发现了HOHO,那我就置顶了嘿嘿!觉得自己技术OK的可以把这套题目做完哦,然后加入高级前端的社区咯
http://www.cnblogs.com/jikey/p/4426105.html js高级前端开发加群方法(此群很难进,里面纯技术,严禁广告,水群) 完整题目做完发邮箱(jikeytang@16 ...
- Node.js系列基础学习----安装,实现Hello World, REPL
Node.js基础学习 简介 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.Node.js是一 ...
随机推荐
- 动态规划——leetcode5、最长回文子串
1.题目描述: 2.解题方法:动态规划 动态规划解题步骤: 1.确定状态 最后一步:如果s[i,...,j]是回文子串,那么需要满足两个条件 ① s[i] == s[j]: ② s[i+1,...,j ...
- 网卡限速工具之WonderShaper
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 什么是WonderShaper 如何安装Wonder ...
- 第五十七篇:webpack打包发布
好家伙,到了打包发布这一步了 1.配置打包命令: 在package.json 文件的 scripts 节点下,新增 build 命令如下: "scripts": { "d ...
- Docker实用篇
Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦. 分布式系统中,依赖的组件非常多,不同组件之间 ...
- CPU流水线与指令乱序执行
青蛙见了蜈蚣,好奇地问:"蜈蚣大哥,我很好奇,你那么多条腿,走路的时候先迈哪一条啊?" 蜈蚣听后说:"青蛙老弟,我一直就这么走路,从没想过先迈哪一条腿,等我想一想再回答你 ...
- Windows客户端DNS工作原理
通常大家对Windows客户端DNS的配置存在多个误区. 误区一,配置1个内网DNS,1个外网DNS.解析内网的时候用内网DNS,解析外网的时候用外网. 电脑怎么知道哪个是内网?哪个是外网?我们内部的 ...
- salesforce零基础学习(一百一十八)Restrict Rule
本篇参考: https://help.salesforce.com/s/articleView?id=sf.security_restriction_rule.htm&type=5 https ...
- KubeOperator界面,集群详情中的存储,存储提供商
点击"添加",假设选择的类型是rook-ceph,表示的是在这个k8s集群里创建rook-ceph集群,而不是显示已经存在的集群 意味着可以使用这种办法在k8s集群里创建rook- ...
- 第一个Django应用 - 第六部分:静态文件
前面我们编写了一个经过测试的投票应用,现在让我们给它添加一张样式表和一张背景图片. 除了由服务器生成的HTML文件外,WEB应用一般需要提供一些其它的必要文件,比如图片文件.JavaScript脚本和 ...
- filebeat直接给es传输日志,自定义索引名,自定义多个索引文件
官方文档地址: https://www.elastic.co/guide/en/beats/filebeat/7.3/elasticsearch-output.html https://www.ela ...