浏览器内核介绍
JS开发环境搭建
JS语法
- 单行注释 : //
- 多行注释 : /*注释内容*/
- 标识符 : 字母数字线划线与美元符号,不能以数字开头 大小写敏感
- 声明变量
语法 | 解释 |
---|---|
var | 声明变量 |
let | 声明一个块作用域中的局部变量 |
const | 声明一个常量 |
数据类型
名称 | 说明 |
---|---|
number | 整型与浮点型 |
boolean | 布尔型 true和false |
string | 字符串 |
null | 空值 |
undefined | 变量声明但未赋值;对象未定义的属性 |
symbol | ES6引入的新类型 |
object类型 | 以上类型的复合,是容器 |
运算符优先级
if语句
if (cond1){
...
}
esle if (cond2){
...
}
esle {
...
}
var score = 100
if (90 <= score && score<= 100 ){
console.log(score,'A Level')}
else if (80 <= score && score < 90){
console.log(score,'B Level')}
else if (70 <= score && score < 80){
console.log(score,'C Level')}
else if (60 <= score && score < 70){
console.log(score,'D Level')}
else if (score < 60) {
console.log(score,"Can't passed")}
else {
console.log('invalid score')
}
switch…case分支语句(注意穿透问题)
switch (expression){
case label1:
statement1
[break;]
case label2:
statement2
[break;]
...
default:
statement_default
[break;]
}
for循环
for (i=1;i<10;i++){
console.log(i)
}
for (i=1,j=9;i<10,j>0;i++,j--){
console.log(i,j)
}
var f=3.14
var arr=[8,'45',f,null]
for (i in arr){
console.log(i,arr[i])
}
--------------------------
0 8
1 45
2 3.14
3 null
var f=3.14
var arr=[8,'45',f,null]
for (i of arr){
console.log(i,)
}
------------------------
8
45
3.14
null
函数
//简单函数定义,可用默认值
function name(a=3,b=5,c=7) {
return a+b-c
}
//有名称的函数表达式
const add_sub = function fn(a = 3, b = 5, c = 7) {
return a + b - c
}
//匿名函数表达式
const add_sub_anno = function (a = 3, b = 5, c = 7) {
return a + b - c
}
console.log(add_sub_anno())
//箭头函数
const name=(a=2,s=4,d=2) => a+s-d
console.log(name())
//递归函数
const sum = function s(n) {
if (n==1) return n;
return n + s(--n)
}
//counter函数
const counter = function () {
let c = 0
return function () {
return ++c
}
}
const c=counter()
console.log(c(),c(),c())
//map函数
function map(arr=[5,2.8,3.14],fn=(x)=>x) {
newarr=[]
for (i in arr){
newarr[i]=fn(arr[i])
}
return newarr
}
console.log(map(),map([5, 2.8, 3.14],(x)=>x+2))
--------------------------------------------------------------------
[ 5, 2.8, 3.14 ] [ 7, 4.8, 5.140000000000001 ]
//map函数 生成器版本
function* map(arr=[5,2.8,3.14],fn=(x)=>x) {
newarr=[]
for (i in arr)
yield fn(arr[i])
}
j = map([5, 2.8, 3.14], (x) => x + 2)
console.log(j.next())
for (i of j){
console.log(i)
}
--------------------------------------------------------------------
{ value: 7, done: false }
4.8
5.140000000000001
//可变参数
function name(...params) {
console.log(1,params,typeof params)
console.log(2,arguments)
for (i of params)
console.log(i)
}
console.log(name(2,56,'ghkj'))
--------------------------------------------------------------------
[ 2, 56, 'ghkj' ] 'object'
{ '0': 2, '1': 56, '2': 'ghkj' }
2
56
ghkj
undefined
//参数解构
para = [ [5, 2.8, 3.14], (x) => x + 2 ]
console.log(map( ...para ))
--------------------------------------------------------------------
[ 7, 4.8, 5.140000000000001 ]
面向对象
//字面声明类
var obj={
pro1 : value1,
pro2 : value2,
pro3 : value3,
//...
}
//ES6之前-构造器
function Point(x,y) {
this.x=x
this.y=y
this.show = () => console.log(this,this.x,this.y)
console.log('Point~~~~~~~~~~~~~~')
}
p1=new Point(1,2)
p2=new Point(3,4)
p1.show()
p2.show()
//继承
function Point3D (x,y,z) {
Point.call(this,x,y) //继承Point
this.z=z
this.show = () => console.log(this, this.x, this.y,this.z)
console.log('Point3D~~~~~~~~~~~~~~')
}
p3=new Point3D(2,4,8)
p3.show()
//ES6中的class
class Point{
constructor(x,y){
this.x=x
this.y=y
}
show(){
console.log(this,this.x,this.y)
}
}
p1=new Point(3,4)
p1.show()
//继承
class Point3D extends Point{
constructor(x,y,z){
super(x,y)
this.z=z
this.show = () => console.log(this, this.x, this.y, this.z)
}
showself(){
console.log(this)
}
}
p2=new Point3D(3,4,5)
p2.show()
p2.showself()
//静态方法
class Point{
constructor(x,y){
this.x=x
this.y=y
}
static show(){
console.log('Static method')
}
}
p1=new Point(3,4)
p1.constructor.show()
Point.show()
//不同函数调用方式引起this对应的对象不同
var school={
name:'xxyg',
getname : function () {
console.log(this.name,this)
return function () {
console.log(this===global)
return this.name
}
}
}
console.log(school.getname()())
--------------------------------------------------------------------
xxyg { name: 'xxyg', getname: [Function: getname] }
true
undefined
//最后返回的this.name已经不是xxygle
//解决办法1,内层函数再次传参
var school={
name:'xxyg',
getname : function () {
console.log(this.name,this)
return function (obj) {
console.log(this===global)
return obj.name
}
}
}
console.log(school.getname()(school))
--------------------------------------------------------------------
xxyg { name: 'xxyg', getname: [Function: getname] }
true
xxyg
//原有代码不用改.改用call或apply调用
console.log(school.getname().call(school))
--------------------------------------------------------------------
xxyg { name: 'xxyg', getname: [Function: getname] }
false
xxyg
console.log(school.getname().apply(school))
--------------------------------------------------------------------
xxyg { name: 'xxyg', getname: [Function: getname] }
false
xxyg
//原有代码不用改.改用bind调用
console.log( school.getname().bind(school)() )
--------------------------------------------------------------------
xxyg { name: 'xxyg', getname: [Function: getname] }
false
xxyg
//使用ES6引入的箭头函数
var school={
name:'xxyg',
getname : function () {
console.log(this.name,this)
return () => {
console.log(this===global)
return this.name
}
}
}
console.log(school.getname()())
--------------------------------------------------------------------
xxyg { name: 'xxyg', getname: [Function: getname] }
false
xxyg
//此类可用ES6新语法定义
class school{
constructor(){
this.name='xxyg'
}
getname(){
console.log(this.name, this)
return () => {
console.log(this === global)
return this.name
}
}
}
console.log(new school().getname()())
--------------------------------------------------------------------
xxyg { name: 'xxyg', getname: [Function: getname] }
false
xxyg
异常捕获
- try…catch语句
- try…catch…finall语句
try {
throw new Error('your error')
// throw new ReferenceError('Ref err')
// throw 1
// throw new Number(100)
// throw 'not OK'
// throw [1,2,4]
// throw {'a':1}
} catch (error) {
console.log(typeof error)
console.log(error.constructor.name)
}finally{
console.log('===end===');
}
模块化
- export 从模块中导出函数 对象 数值,供其他模块导入使用
- import 导入另一个模块导出的绑定
- 导出 建一个模块目录src,目录下新建moda.js文件 内容如下
//缺省导出
export default class A{
constructor(x){
this.x=x
}
show(){
console.log(this.x);
}
}
//导出函数
export function B(params) {
console.log('fn test');
}
//导出常量
export const C=1
- 导入 在src的同级目录新建js文件,内容如下. 即可导入上面模块导出的数据
import {A,B,C} from "./src/moda"
import * as mod_a from "./src/moda"
a=new A(34)
console.log(a.show(),B(),mod_a.C
重要说明 : 该语法太新,当前使用的稳定版nodejs版本为8.11.3,都不支持.因此需要转译为低版本
转译
什么是转译?
- 转译是指从一种语言代码转到另一种语言代码,又指某一语言从高版本转向低版本
为什么要转译 :
- 开发时用新版本语法写的js脚本,在用户低版本js引擎的浏览器中不一定支持.因此需要将高版本的代码作降级处理
- 常用转译工具 : bable
- babel可将开发时用的ES6语法转译为当前大多数浏览器支持的语法
- babel官网 : http://babeljs.io/
- 环境配置 :
- [初始化] 项目根目录运行 npm init ,一路回车 在项目根目录生成package.json文件
- [修改下载源] 生成内容为”registry=https://registry.npm.taobao.org“的.npmrc文件 (参考命令
echo "registry=https://registry.npm.taobao.org" > ~/.npmrc
)该文件可放置于三个目录 - nodejs根目录下的node_modules\npm目录
- 用户家目录
- 项目根目录
- [安装babel] 项目根目录下执行
npm install babel-core babel-cli --save-dev
命令 - [修改pack.json文件] 替换scripts部分
{
"name": "jspack",
"version": "1.0.0",
"description": "babel_test",
"main": "index.js",
"directories": {
"lib": "lib"
},
"scripts": {
"build": "babel src -d lib"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-preset-env": "^1.7.0"
}
}
[配置babel和安装依赖]项目根目录创建内容为’{“presets”:[“env”]}’的.babelrc文件 在项目根目录执行以下命令 :
echo '{"presets":["env"]}' > .babelrc
[准备js文件]
- 项目根目录分别创建src和lib目录,src目录存放新语法的js文件,src目录用于生成兼容的js文件
- src目录生成mod.js和index.js文件
/src/mod.js内容如下 :
export default class {
constructor(x){
this.x=x
}
show(){
console.log(this.x);
}
}
function B() {
console.log('fn test');
}
let x='Javascript'
var y='ES'
const C=6
export {B,x,y,C}
--------------------------------------------------------------------
/src/index.js内容如下 :
import defaultcls, { B, x, y, C } from "./mod"
var a = new defaultcls(34)
a.show()
B()
console.log(x,y,C)
- [转译] 项目根目录运行
npm run build
命令 出现类似下面的内容表示转译成功
> jspack@1.0.0 build D:\js\jspack
> babel src -d lib
src\index.js -> lib\index.js
src\mod.js -> lib\mod.js
- [测试结果] 在VScode下运行lib\index.js文件(亦可使用
node lib\index.js
命令),出现类似下面的内容表示转译成功
34
fn test
Javascript ES 6
解构
//对象解构
const obj={
a:100,
b:200,
c:300
}
let {b,c,a}=obj
console.log(a,b,c);
//100 200 300
var metadata={
title: 'javascript',
trs:[
{
locate:'de',
title:'js'
}
],
url:'/js/es6/2018'
}
var {title:T,trs:[{title:y,locate:l}],url:u}=metadata
console.log(T,y,u,l);
//javascript js /js/es6/2018 de
数组 对象操作
var arr=[1,2,3,4,5]
console.log(arr.push(6, 7)); //返回7
console.log(arr) // [ 1, 2, 3, 4, 5, 6, 7 ]
console.log(arr.pop());//返回7
console.log(arr) // [ 1, 2, 3, 4, 5, 6 ]
const fi = (x) =>{
if (!(x % 2) && x*x>10 ){
return true
}
}
//js的filter与map函数与python的同名函数类似
console.log(arr.filter(fi))
console.log(arr.map(x=>x+20))
//foreach这么用
var newarr = []
const fc = (x) => {
if (!(x % 2) && x * x > 10) {
newarr.push(x+5)
}
}
arr.forEach(fc)
console.log(newarr);
const obj={
a:100,
b:200,
c:300
}
console.log(Object.keys(obj)) //[ 'a', 'b', 'c' ]
for (i in obj){
console.log(i,obj[i]);
}
//-----------------
// a 100
// b 200
// c 300
var metadata = {
b:66,
title: 'javascript',
trs: [
{
locate: 'de',
title: 'js'
}
],
url: '/js/es6/2018'
}
console.log(1,Object.assign({c:34,d:67},obj));
console.log(2,obj);
console.log(3,Object.assign(metadata,obj));
console.log(4,obj);
// 1 { c: 300, d: 67, a: 100, b: 200 }
// 2 { a: 100, b: 200, c: 300 }
// 3 {
// b: 200,
// title: 'javascript',
// trs: [{ locate: 'de', title: 'js' }],
// url: '/js/es6/2018',
// a: 100,
// c: 300
// }
// 4 { a: 100, b: 200, c: 300 }
Promise
var mypromise = new Promise(
(resolve,reject)=>{
resolve('Accomplished')
reject('Failed')
}
)
console.log(mypromise);
mypromise.then(
// function name(value) {
// console.log(1,mypromise,value);
// return '1st-then'
// }
(value)=>console.log(1,mypromise,value),
(reason)=>console.log(2,mypromise,reason)
).then(
function (params) {
console.log(3,params);
return Promise.reject(params+' failed')
}
).catch(reason =>{
console.log(4,reason);
return Promise.resolve(reason)
}
)
异步实例 :
function runAsync() {
return new Promise(
function (resolve,reject) {
setTimeout(() => {
console.log(1,'do sth ...')
resolve('ok')},
3000)
}
)
}
runAsync().then(value=>{
console.log(2,value);
return Promise.reject(value+' failed 1st')
}
).catch(reason=>{
console.log(3,reason);
return Promise.resolve(reason+' succeed 2nd')
}
).then(value=>{
console.log(4,value);
console.log(5,'END');
}
)
console.log(6,'Final EDN');
- 简而言之,Promise对象用于对异步操作最终结果(失败或成功)的表示.用于处理异步请求.
- Promise意为承诺,即承诺成功如何处理,失败如何处理
React
- React是Facebook开发并开源的前端框架.2013年Read开源.解决的是前端MVC框架中的VieW视图层的问题
- 项目根目录安装好依赖 运行
npm start
命令可启动Webserver - 在VScode中修改/src/index.js文件 保存以后可自动转译,重新载入页面
- index.js 定义了Toggle和Root两个组件 可动态生成HTML页面 改变组建状态(state),重新渲染(render)页面
import React from 'react';
import ReactDom from 'react-dom';
class Toggle extends React.Component {
state = { flag: true }
handleClick(event) {
// console.log(1,event.target.id);
// console.log(2,event.target === this);
// console.log(3,this);
// console.log(4,this.state);
this.setState({ flag: !this.state.flag })
// this.state.flag = !this.state.flag
}
render() {
return (
<button id="t1" onClick={this.handleClick.bind(this)}>
click here and trig one event {this.state.flag.toString()}
</button>
)
}
}
class Root extends React.Component {
state = { p1: '6k93', p2: '.cn' }
render() {
setTimeout(() => this.setState({ p1: 'www.6k93' }), 3000);
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
<Toggle />
</div>
)
}
}
ReactDom.render(<Root />, document.getElementById('root'))
- 属性 props
import React from 'react';
import ReactDom from 'react-dom';
class Toggle extends React.Component {
state = { flag: true }
handleClick(event) {
// console.log(1,event.target.id);
// console.log(2,event.target === this);
// console.log(3,this);
// console.log(4,this.state);
this.setState({ flag: !this.state.flag })
// this.state.flag = !this.state.flag
}
render() {
return (
<button id="t1" onClick={this.handleClick.bind(this)}>
click here and trige one event
<br/>{this.props.name}:
{this.props.parent.state.p1 + this.props.parent.state.p2}
<br />{this.props.children}
</button>
)
}
}
class Root extends React.Component {
state = { p1: '6k93', p2: '.cn' }
render() {
setTimeout(() => this.setState({ p1: 'www.6k93' }), 3000);
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
<Toggle name="school" parent={this}>
<hr/>
<span> 我是Toggle的子元素</span>
</Toggle>
</div>
)
}
}
ReactDom.render(<Root />, document.getElementById('root'))
- 构造器constructor
- 使用ES6的构造器,需要提供一个参数props,并把这个参数使用super传给父类
import React from 'react';
import ReactDom from 'react-dom';
class Toggle extends React.Component {
constructor(props){
super(props)
this.state = { flag: true }
}
handleClick(event) {
// console.log(1,event.target.id);
// console.log(2,event.target === this);
// console.log(3,this);
// console.log(4,this.state);
this.setState({ flag: !this.state.flag })
// this.state.flag = !this.state.flag
}
render() {
return (
<button id="t1" onClick={this.handleClick.bind(this)}>
click here and trige one event
<br/>{this.props.name}:
{this.props.parent.state.p1 + this.props.parent.state.p2}
<br />{this.props.children}
</button>
)
}
}
class Root extends React.Component {
constructor(props){
super(props)
this.state = { p1: '6k93', p2: '.cn' }
}
render() {
setTimeout(() => this.setState({ p1: 'www.6k93' }), 3000);
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
<Toggle name="school" parent={this}>
<hr/>
<span> 我是Toggle的子元素</span>
</Toggle>
</div>
)
}
}
ReactDom.render(<Root />, document.getElementById('root'))
- 无状态组件/函数式组件
- 输入参数props,返回React元素
- 无状态组件函数实质上为render函数
- React自15.0开始支持 定义如下
import React from 'react';
import ReactDom from 'react-dom';
function Root(props) {
return <div>{props.name}</div>
}
//let Root = props => <div>{props.name}</div>
ReactDom.render(<Root nmae='React'/>, document.getElementById('root'))
高阶函数/装饰器
- 为Root组件增加属性
let Root= props => <div>{props.name}</div>
let Wrapper = function (Compoment,props) {
return(
<div>
{props.name}
</hr>
<Compoment/>
</div>
)
}
//调用方式:
Wrapper(Root,'addprops')
- 柯里化 :
let Wrapper = function (Compoment) {
_Wraper = function (props) {
return (
<div>
{props.name}
</hr>
<Compoment />
</div >
}
return _Wraper
}
//调用方式:
Wrapper(Root)('addprops')
- 转化为箭头函数 :
let Wrapper = Compoment => props =>
(<div>
{props.name}
</hr>
<Compoment />
</div >)
//调用方式:
Wrapper(Root)('addprops')
装饰器语法
- ES2016引入装饰器,但只能装饰类
import React from 'react';
import ReactDom from 'react-dom';
let Wrapper = Compoment => props => (
<div>{props.name} <hr/> <Compoment/></div>)
@Wrapper
class Root extends React.Component{
render(){
return <div>I am Root</div>
}
}
ReactDom.render(<Root />, document.getElementById('root'))
- 带参装饰器
import React from 'react';
import ReactDom from 'react-dom';
let Wrapper = id => Compoment => props => (
<div id={id}>{props.name} <hr /> <Compoment /></div>)
@Wrapper('2018')
class Root extends React.Component {
render() {
return <div>I am Root</div>
}
}
ReactDom.render(<Root name='React'/>, document.getElementById('root'))