惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
GbyAI
GbyAI
月光博客
月光博客
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
F
Full Disclosure
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
博客园 - Franky
V
V2EX
Recorded Future
Recorded Future
WordPress大学
WordPress大学
小众软件
小众软件
Webroot Blog
Webroot Blog
雷峰网
雷峰网
Vercel News
Vercel News
N
News and Events Feed by Topic
PCI Perspectives
PCI Perspectives
Cyberwarzone
Cyberwarzone
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
W
WeLiveSecurity
S
Schneier on Security
博客园 - 三生石上(FineUI控件)
K
Kaspersky official blog
F
Fortinet All Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Spread Privacy
Spread Privacy
博客园 - 叶小钗
罗磊的独立博客
D
Docker
Forbes - Security
Forbes - Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Register - Security
The Register - Security
A
About on SuperTechFans
B
Blog RSS Feed
I
InfoQ
T
Tailwind CSS Blog
G
Google Developers Blog
H
Help Net Security
V
Vulnerabilities – Threatpost
AWS News Blog
AWS News Blog
N
News and Events Feed by Topic
M
MIT News - Artificial intelligence
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Proofpoint News Feed
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
MyScale Blog
MyScale Blog
Latest news
Latest news

风萧古道 - 勤学苦练,年复一年

游戏服务器开发经验(五)应对复杂需求 沉浸式体验东汉末年生活 - 《真三国无双 起源》玩后感 怒其不争!致2025年HLTV的Top18-NiKo Linux家用服务器维护指南 游戏服务器开发经验(四)避免写Bug的习惯、技巧和心态 游戏服务器开发经验(三)线上维护 游戏服务器开发经验(二)避免内存泄露 游戏服务器开发经验(一)道具防刷 35岁找不到工作,绝对不会是软件开发人员的结局 用爱发电项目开发两个月的心得体会 以魏延“子午谷奇谋”讨论软件需求可行性问题 MQTT协议中可变长度的具体计算方式(有计算过程解析) 关于游戏服务器配置表功能的探讨 Java并发编程中上锁的几种方式 如何用C++分割一个字符串? CSAPP第二章-信息的表示与处理 我的自我介绍 Windows XP虚拟机中文版无需激活下载 Java TreeSet的一些用法和特性 Linux C++ Socket实战 传统软件服务器与游戏服务器架构区别 独立个人项目开发心得 - 任务切分、挑战性、实用性和半途而废 使用Python实现简单UDP Ping 使用Python开发一个简单的web服务器 Kotlin手动实现一个最简单的哈希表 Kotlin实现二叉堆、大顶堆、优先级队列 搭建Spark实战环境(3台linux虚拟机集群)(一)样板机的搭建 Springboot操作MongoDB,包括增改查及复杂操作 Unison在Linux下的安装与使用 Java实现类似WINSCP访问远程Linux服务器,执行命令、上传文件、下载文件 一个被废弃的项目——自动爬取信息然后发给我自己邮箱上 Python连接MongoDB和Oracle实战 MongoDB常用查询语句 vue和springboot项目部署到Linux服务器 Python的一些用法(可能不定时更新) java正则表达式 - 双反斜杠(\)和Pattern的matches()与find() 简述爬虫对两种网站的不同爬取方式 Vue的路由配置及手动改地址栏为啥又跳转回来?? [Mybatis]逆向工程中Select语句查询不出‘TEXT’字段 [编译原理]FIRST、FOLLOW和SELECT [Spring]Spring学习笔记 [算法]分布估计算法 - 一种求解多维背包问题的混合分布估计算法_王凌 [日常]我做独立博客的原因 人间值得 深入理解计算机系统 想想就开心! 最重要的事,只有一件 藏书 被讨厌的勇气 关于 简历 朋友 尊重自己:给予与接收的心灵艺术
[JavaScript]JS基础知识
JonathanLin · 2018-06-06 · via 风萧古道 - 勤学苦练,年复一年

变量类型及计算

变量类型

值类型 vs  引用类型

值类型:

var a = 100
var b = a
a = 200
console.log(b) //100

引用类型:

var a = {age:20}
var b = a
b.age = 21
console.log(a.age) //21

引用类型:对象、数组和函数

特点:无限扩展属性,内存占用可能过大,故共用内存空间以节省空间

Typeof运算符详解

typeof undefined	//undefined
typeof 'abc'		//string
typeof 123		//number
typeof true		//boolean
typeof {}		//object
typeof []		//object
typeof null		//object
typeof console.log	//function

注:null也是对象

1~4行是值类型,5~8行是引用类型,但JS只能区分函数与非函数,而不能区分数组和对象。

变量计算

强制类型转换

字符串拼接

var a = 100 + 10
var b = 100 + '10'
console.log(a)	//110
console.log(b)	//10010

数字 + 字符串时将数字自身转为字符串。

==运算符

console.log(100 == '100')		//true
console.log(0 == '')			//true
console.log(null == undefined)		//true

==计算会试图让前后的比较对象相等,故发生类型转换

if语句

var a = true
if(a){
    console.log('a');
}
var b = 100
if(b){
    console.log('b')
}
var c = ''
if(c){
    console.log('c')
}
//输出 a 
//     b
//(c不输出)

100被强制转换为true,而’’被转换为false

逻辑运算

console.log(10 && 0)		//0
console.log('' || 'abc')	//abc
console.log(!window.abc)	//true
	
//判断一个变量会被当成true 还是 false
var a = 100
console.log(!!a)		//true

题目:

1、何时使用 === 何时使用 == ?

if(obj.a == null){
	//相当于 obj.a === null || obj.a === undefined 的简写形式
	//jQuery源码推荐写法
}

除了这种情况外,全部使用===

2、JS中有哪些内置函数

  • Object
  • Array
  • Boolean
  • Number
  • String
  • Function
  • Date
  • RegExp
  • Error

3、如何理解JSON?

Json既是数据格式,也是数据对象。

JSON.stringify({a:10,b:20})
JSON.parse('{"a":10,"b":20}')

原型和原型链

构造函数

function Foo(name,age){
    this.name = name
    this.age = age
    this.class = 'class-1'
    //return this  //默认有这一行
}
var f = new Foo('zhangsan',20)
//var f1 = new Foo('lisi',21)	//创建多个对象

构造函数需使用大写开头!

扩展:

var a = {} 其实是 var a = new Object() 的语法糖

Var a = [] 其实是 Var a = new Array() 的语法糖

Function Foo(){…} 其实是 var Foo = new Function(…)的语法糖

使用instanceof判断一个函数是否是一个变量的构造函数

判断一个变量是否为“数组”: 变量 instanceof Array

5条原型规则

1、所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了null以外)

var obj = {};obj.a = 100;
var arr = [];arr.a = 100;
function fn(){}
fn.a = 100

2、所有的引用类型(数组、对象、函数),都有一个__proto__属性,属性值是一个普通的对象。(隐式原型)

console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);

输出结果:

3、所有的函数,都有一个prototype属性,属性值也是一个普通的对象(显式原型)

console.log(fn.prototype)

输出结果 4、所有的引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的“prototype”属性值

console.log(obj.__proto__ === Object.prototype)  //true

5、当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找

function Foo(name, age){
    this.name = name
}
Foo.prototype.alertName = function(){
    alert(this.name)
}
//创建示例
var f = new Foo('zhangsan')
f.printName = function(){
    console.log(this.name);
}
//测试
f.printName()
f.alertName()

this:

永远指向f自身,故能读取属性

循环对象自身的属性

var item
for (item in f){
    //高级浏览器已经在for in中屏蔽了来自原型的属性
    //但是建议还是加判断
    if(f.hasOwnProperty(item)){
        console.log(item)
    }
}

原型链

function Foo(name, age){
    this.name = name
}
Foo.prototype.alertName = function(){
    alert(this.name)
}
//创建示例
var f = new Foo('zhangsan')
f.printName = function(){
    console.log(this.name);
}
//测试
f.printName()
f.alertName()
f.toString() // 要去f.__proto__.__proto__中查找

注意,toString()是Object.prototype中的方法,f通过读取__proto__的方式寻找该方法,但它的上一级原型并没有这个方法,故寻找隐式原型的隐式原型,最终在Object中找到了toString()方法。

Instanceof的用法介绍

用于判断引用类型属于哪个构造函数的方法

F instanceof Foo 的判断逻辑是:

F 的 proto 一层一层往上,能否对应到 Foo.prototype

再试着判断 f instanceof Object

题目:

1、如何准确判断一个变量是数组类型

var arr = []
arr instanceof Array	// true
typeof arr 	//Object

2、写一个原型链继承的例子

封装DOM查询:

function Elem(id){
    this.elem = document.getElementById(id)
}
Elem.prototype.html = function(val){
    var elem = this.elem
    if(val){
        elem.innerHTML = val
        return this   //链式操作
    }else{
        return elem.innerHTML
    }
}
Elem.prototype.on = function(type, fn){
    var elem = this.elem
    elem.addEventListener(type,fn)
    return this
}
var div1 = new Elem('div1')
//console.log(div1.html())

div1.html('<p>hello world</p>')
div1.on('click',function(){
    alert('clicked')
})
//链式操作
div1.html('<p>hello world</p>').on('click',function(){
    alert('clicked')
})

3、描述new一个对象的过程

function Foo(name,age){
    this.name = name
    this.age = age
    this.class = 'class-1'
    //return this  //默认有这一行
}
var f = new Foo('zhangsan',20)
  1. 创建一个新对象
  2. this指向这个新对象
  3. 执行代码,即对this赋值
  4. 返回this

[JavaScript]JS基础知识(中)

作用域和闭包

执行上下文

范围:一段<script>或者一个函数

全局:变量定义、函数声明(一段<script>)

函数:变量定义、函数声明、this、arguments(函数)

console.log(a) //undefined
var a = 100
   
fn('zhangsan')  //zhangsan 20
function fn(name){
    //函数内
    age = 20
    console.log(name, age)
    var age
      
    bar(100)
    function bar(num){
        console.log(num)
    }
}

在第2行执行之前,a被声明为undefined,而在第5行执行时,函数fn直接被提前完整声明了,所以可以正确执行。

在第6~15行,是函数内的执行上下文,同理,在第8行中读取age的属性,自动为age完成了“var age”的声明,故程序可正常执行。

建议定义要放前面,方便他人阅读。

在函数fn中,bar(100)也会去寻找function bar()的声明,故也能正常输出数字。

关于this、argument,在函数执行之前,this就已经确定了值。

注意“函数声明”和“函数表达式”的区别

//函数声明
function fn(){
    //声明
}
//函数表达式
var fn = function(){
    //表达式
}

注意,执行第1行时,如果是用函数声明的方式定义函数,则可以执行,而使用函数表达式的方式,则报错,因为找不到函数的定义。

this

作为构造函数执行:

function Foo(name){
    this.name = name
}

var f = new Foo("zhangsan")

作为对象属性执行:

var obj = {
    name: 'A',
    printName: function(){
        console.log(this.name)
    }
}
obj.printName()

作为普通函数执行:

function fn(){
    console.log(this)   //this === window
}
fn()

call apply bind:

function fn1(name,age){
    alert(name)
    console.log(this)
}
fn1.call({x:100},'zhangsan',20)
fn1.apply({x:100},['zhangsan',20])

var fn2 = function(name,age){
    alert(name)
    console.log(this)
}.bind({y:200})
fn2('zhangsan',20)

call、apply和bind可以修改this的值。其中要注意bind必须要用函数表达式的方式才能执行。

作用域

js中,无块级作用域:

if(true){
    var name = 'zhangsan'
}
console.log(name)   //zhangsan

外部可以访问if语句块中的name

有函数和全局作用域:

var a = 100
function fn(){
    var a = 200
    console.log('fn',a) //fn 200
}
console.log('global',a) //global 100
fn()

由于有函数作用域和全局作用域,故两次输出a的值不同。定义到函数里的变量,外部不可调用、改变。

作用域链

关于自由变量:

var a = 100
function fn(){
    var b = 200 //当前作用域中没有定义的变量,即“自由变量”
    console.log(a)
    console.log(b)
}
fn()

在fn函数中,并没有定义a,但是fn从其父级作用域中寻找变量。

函数的作用域是由函数定义的时候指定的,而不是函数执行时指定的。

关于作用域链:

var a = 100
function f1(){
    var b = 200
    function f2(){
        var c = 300
        console.log(a)  //自由变量
        console.log(b)  //自由变量
        console.log(c)
    }
    f2()
}
f1()

F1的父级作用域是全局作用域,f2的父级作用域是f1,因此当打印a时,js向父级作用域中寻找,而f1作用域没有,则再往f1的父级作用域,即全局作用域中寻找,再全局作用域中找到a,而b也同理。

这个寻找的过程是从作用域链中一步步寻找得到的,这就是作用域链。

闭包

函数作为返回值的情况:

function F1(){
    var a = 100
    
    //返回一个函数(函数作为返回值)
    return function(){
        console.log(a)
    }
}

//f1得到一个新函数
var f1 = F1()
a = 200
f1()  // 10

F1函数返回了一个函数。将返回的函数赋值给了f1,之后执行f1。

在第5行中,a是自由变量,故到它的父级作用域中寻找,而F1()函数中定义了a = 100,所以a的值为100。

函数作为参数传递的情况:

function F1(){
    var a = 100
    
    //返回一个函数(函数作为返回值)
    return function(){
        console.log(a)
    }
}
var f1 = new F1()

function F2(fn){
    a = 200
    fn()
}
F2(f1); //还是 100

题目:

1、说一下对变量提升的理解:

变量定义 函数声明(注意和函数表达式的区别)

2、说明this几种不同的使用场景

作为构造函数执行 作为对象属性执行 作为普通函数执行 Call apply bind

3、创建10个<a>标签,点击的时候弹出来对应的序号

错误代码:

var i,a
for(i = 0;i &lt; 10;i++){
    a = document.createElement('a')
    a.innerHTML = i + '&lt;br/&gt;'
    a.addEventListener('click',function(e){
        e.preventDefault()
        alert(i)
    })
    document.body.appendChild(a)
}

执行结果:无论点击哪个链接,都弹出10。原因是在全局作用域中,i在循环结束时的值为10,所以不管之前定义时i的值为多少,总是返回当前作用域的i的值。

正确解法:使用自执行函数(就是不用调用,只要定义完成,立即执行的函数)

正确代码:

var i
for(i = 0;i &lt; 10;i++){
    (function(i){
        //存在自己的函数作用域
        var a = document.createElement('a')
        a.innerHTML = i + '&lt;br/&gt;'
        a.addEventListener('click',function(e){
        e.preventDefault()
        alert(i)
    })
    document.body.appendChild(a)
    })(i)   
}

结果截图:

[JavaScript]JS基础知识(下)

异步和单线程

异步

console.log(100)
setTimeout(function(){
    console.log(200)
},1000)
console.log(300)
//输出:
//100
//300
//200(过了1秒后)

同步

console.log(100)
alert(200)
console.log(300)
//在弹窗弹出200时,控制台是不打印300的,直到弹框结束才打印300

同步会阻塞下面代码的执行,什么时候消除阻塞,才会继续往下走。

异步不会阻塞,只是继续等待。

异步同步的差异在于,会不会阻塞后续代码的执行。

何时需要异步?

在可能发生等待的情况。

等待过程中不能像alert一样阻塞程序执行。

因此,所有的“等待的情况”都需要异步。

前端使用异步的场景

定时任务:setTimeout(设置多少毫秒之后执行函数体),setInterval(设置每多少毫秒之后执行函数体)

console.log(100)
setTimeout(function(){
    console.log(200)
},1000)
console.log(300)
//输出:
//100
//300
//200(过了1秒后)

网络请求:ajax请求:

console.log('start')
$.get('./data1.json',function(data1){
	console.log(data1)
})
console.log('end')

动态<img>加载:

console.log('start')
var img = document.createElement('img')
img.onload = function(){
    console.log('loaded')
}
img.src = 'img/HBuilder.png'
console.log('end')

事件绑定:

console.log('start')
document.getElementById('div1').addEventListener('click',function(){
    alert('clicked')
})
console.log('end')

异步和单线程

console.log(100)
setTimeout(function(){
    console.log(200)
},1000)
console.log(300)
//输出:
//100
//300
//200(过了1秒后)

执行第1行,打印100,

执行setTimeout后,传入setTimeout函数会被暂存起来,不会立即执行(单线程的特点,不能同时干两件事),

执行最后一行,打印300,

待所有程序执行完,处于空闲状态时,会马上查看有没有暂存起来的要执行的函数,

发现暂存起来的setTimeout中的函数无需等待时间,就立即发过来执行。

题目

1、同步和异步的区别是什么?分别举一个同步和异步的例子。

同步会阻塞代码执行,而异步不会。

Alert是同步,setTimeout是异步。

2、一个关于setTimeout的笔试题:

console.log(1)
setTimeout(function(){
    console.log(2)
},0)
console.log(3)
setTimeout(function(){
    console.log(4)
},1000)
console.log(5)

输出:1 3 5 2 4

3、前端使用异步的场景有哪些?

都需要等待,单线程,为了不阻塞,只能等待。

其他知识

日期

Date.now()			//当前时间的毫秒数
var dt = new Date()
dt.getTime() 		//获取毫秒数
dt.getFullYear() 	//年
dt.getMonth() 		//月(0~11)
dt.getDate()		//日(0~31)
dt.getHours()		//小时(0~23)
dt.getMinutes()		//分钟(0~59)
dt.getSeconds()		//秒	 (0~59)

Math

获取随机数Math.random()

数组API

forEach 遍历所有元素:

var arr = [1,2,3]
//参数为 元素,下标,元素在前,下标在后
arr.forEach(function(item, index){
    //遍历数组中的所有元素
    console.log(index,item)
})

every 判断所有元素是否都符合条件:

var arr = [1,2,3]
var result = arr.every(function(item, index){
    //用来判断所有的数组元素,是否都满足一个条件
    if(item &lt; 2){
        return true
    }
})
console.log(result)	//false

some 判断是否有至少一个元素符合条件:

var arr = [1,2,3]
var result = arr.some(function(item, index){
    //用来判断所有的数组元素,只要有一个满足条件即可
    if(item &lt; 2){
        return true
    }
})
console.log(result)	//true

sort 排序

var arr = [1,4,2,3,5]
var arr2 = arr.sort(function(a,b){
	//从小到大排序
	return a - b
})
console.log(arr2)

map 对元素重新组装,生成新数组

var arr = [1,2,3,4]
var arr2 = arr.map(function(item,index){
    //将元素重新组装,并返回
    return '&lt;b&gt;' + item + '&lt;/b&gt;'
})
console.log(arr2)

filter 过滤符合条件的元素:

var arr = [1,2,3]
var arr2 = arr.filter(function(item,index){
    //通过某一个条件过滤数组
    if(item &gt;= 2){
        return true
    }
})
console.log(arr2)

对象API

for in

var obj = {
    x:100,
    y:200,
    z:300
}
var key
for(key in obj){
    if(obj.hasOwnProperty(key)){
        console.log(key,obj[key])
    }
}

题目

1、获取2017-06-10格式的日期

function formatDate(dt){
	if(!dt){
		dt = new Date()
	}
	var year = dt.getFullYear()
	var month = dt.getMonth() + 1
	var date = dt.getDate()
	if(month &lt; 10){
		//强制类型转换
		month = '0' + month
	}
	if(date &lt; 10){
		//强制类型转换
		date = '0' + date
	}
	//强制类型转换
	return year + '-' + month + '-' + date
}
var dt = new Date()
var formatDate = formatDate(dt)
console.log(formatDate)

2、获取随机数,要求是长度一致的字符串格式

var random = Math.random()
random = random + '0000000000'//后面加上10个零
random = random.slice(0,10)
console.log(random)

3、写一个能遍历对象和数组的通用forEach函数

//对数组:
var arr = ['a','b','c']
forEach(arr,function(item,index){
    console.log(index,item)
})
//对对象:
var obj = {
    'one':'a',
    'two':'b'
}
for(key in obj){
    console.log(key,obj[key])
}
//组合后:
function forEach(obj,fn){
    var key
    if(obj instanceof Array){
        //准确判断是不是数组
        obj.forEach(function(item,index){
            fn(index,item)
        })
    }else{
        //不是数组就是对象
        for(key in obj){
            fn(key,obj[key])
        }
    }
}

[JavaScript]JS WEB API(上)

JS WEB API

Ecma262 + w3c

DOM操作

1、DOM是哪种基本的数据结构?树

2、DOM操作的常用API有哪些?

获取DOM节点,以及节点的property和attribute

获取父节点,获取子节点

新增节点,删除节点

3、DOM节点的attr和property有何区别?

Property只是一个js对象的属性的修改

Attribute是对html标签属性的修改

DOM本质

浏览器把拿到的HTML代码,结构化一个浏览器能识别并且js可操作的一个模型而已。

DOM节点操作

获取DOM节点

prototype 获取的是js对象 attribute 获取的是DOM节点

DOM结构操作

新增节点 获取父元素、获取子元素、删除节点

BOM操作

Navigator、Screen Location、History

1、如何检测浏览器的类型?

Navigator

2、拆解url的各部分

location