您好,登錄后才能下訂單哦!
1 定義一個函數(shù)(構造器)對象,使用this定義屬性
2 使用new 和構造器創(chuàng)建一個新對象
當使用new關鍵字后,其函數(shù)的調用將不再是函數(shù),而是一個原型,就以這個原型為模板,構造出自己的實例,然后進行對應的個性化操作,將其當做構造器來處理其特殊的屬性或方法。
//古老的定義對象的方式
var obj= {
a:'abc',
b:'123',
c:'[1,2,3,4]',
}
console.log(obj.a,obj.b,obj.c)
function fn(x){
this.x=x;
}
console.log(typeof(fn)) // 此處返回是一個函數(shù)
function fn1(x,y) {
this.x=x;
this.y=y;
console.log(this) //指代函數(shù)本身,而不是實例化后的結果
console.log(arguments)
}
a=new fn1(10,20) //對象構建,fn1由普通函數(shù)變成了一個構造器,new 先做對象,基于原型將a進行處理,通過對象虧幫屬性
console.log(a.x,a.y)
結果如下
function fn(x,y) {
console.log('fn')
this.x=x; //初始化屬性
this.y=y;
this.show=()=> ('show') //初始化方法,及函數(shù)
}
//繼承
function fn1(x,y,z) {
console.log('fn1')
fn.call(this,x,y); //調用父類構造器,
this.z=z;
}
a=new fn1(1,2,3)
console.log('fn1',a) //此處將a修改成一個對象,及字典,其對象中包含著所有的屬性和方法
console.log(a.show(),a.x,a.y,a.z)
結果如下
1 類的定義使用class 關鍵字,創(chuàng)建的本質還是函數(shù),是一個特殊的函數(shù)
2 一個類只能擁有一個名為constructor的構造方法,如果沒有顯示的定義一個構造方法,則會默認添加一個constructor方法
3 繼承使用extends 關鍵字
4 一個構造器可以使用super關鍵字來調用父類的構造函數(shù)
5 類沒有私有屬性
class fn{ //定義類
constructor(x,y){
console.log('fn')
this.x=x; //定義屬性
this.y=y;
}
show () //定義方法
{
console.log(this,this.x,this.y)
}
}
//繼承關系
class fn1 extends fn{ //使用extends表示繼承
constructor(x,y,z){
console.log('fn1')
super(x,y); //調用父類方法,必須傳入對應的值,否則父類無入值則會報錯。
this.z=z;
}
}
a=new fn1(1,2,3)
console.log(a.show()) //調用父類的方法
console.log(a.x,a.y,a.z)
結果如下
函數(shù)重載及函數(shù)名稱相同,參數(shù)個數(shù)或類型不同,此處稱為重載
子類匯總直接可以重寫父類的方法,如果需要使用父類的方法,則使用super.method()的方式調用
class fn{ //定義類
constructor(x,y){
console.log('fn')
this.x=x; //定義屬性
this.y=y;
}
show () //定義方法
{
console.log(this,this.x,this.y)
}
}
class fn1 extends fn{ //使用extends表示繼承
constructor(x,y,z){
console.log('fn1')
super(x,y); //調用父類方法,必須傳入對應的值,否則父類無入值則會報錯。
this.z=z;
}
show(){ //屬性重載操作
console.log(this,this.x,this.y,this.z)
}
}
a=new fn1(1,2,3)
console.log(a.show()) //重載后的屬性調用
console.log(a.x,a.y,a.z)
結果如下
使用箭頭函數(shù)重寫方法
class fn{ //定義類
constructor(x,y){
console.log('fn')
this.x=x; //定義屬性
this.y=y;
}
show = () => console.log(this,this.x,this.y)
}
class fn1 extends fn{ //使用extends表示繼承
constructor(x,y,z){
console.log('fn1')
super(x,y); //調用父類方法,必須傳入對應的值,否則父類無入值則會報錯。
this.z=z;
}
show = () => console.log(this,this.x,this.y,this.z)
}
a=new fn1(1,2,3)
console.log(a.show()) //重載后的屬性調用
console.log(a.x,a.y,a.z)
class fn{ //定義類
constructor(x,y){
this.x=x; //定義屬性
this.y=y;
this.show=() => console.log('this fn',this.x,this.y)
}
show = () => console.log('fn',this.x,this.y)
}
class fn1 extends fn{ //使用extends表示繼承
constructor(x,y,z){
super(x,y); //調用父類方法,必須傳入對應的值,否則父類無入值則會報錯。
this.z=z;
this.show=() => console.log('this fn1',this.x,this.y,this.z);
}
show = () => console.log('fn1',this.x,this.y,this.z);
}
a=new fn1(1,2,3)
console.log(a.show())
結果如下
此處默認調用的是子類的屬性,
class fn{ //定義類
constructor(x,y){
this.x=x; //定義屬性
this.y=y;
this.show=() => console.log('this fn',this.x,this.y)
}
show = () => console.log('fn',this.x,this.y)
}
class fn1 extends fn{ //使用extends表示繼承
constructor(x,y,z){
super(x,y); //調用父類方法,必須傳入對應的值,否則父類無入值則會報錯。
this.z=z;
// this.show=() => console.log('this fn1',this.x,this.y,this.z);
}
show = () => console.log('fn1',this.x,this.y,this.z);
}
a=new fn1(1,2,3)
console.log(a.show())
結果如下
此處調用的是子類的方法
class fn{ //定義類
constructor(x,y){
this.x=x; //定義屬性
this.y=y;
this.show=() => console.log('this fn',this.x,this.y)
}
show = () => console.log('fn',this.x,this.y)
}
class fn1 extends fn{ //使用extends表示繼承
constructor(x,y,z){
super(x,y); //調用父類方法,必須傳入對應的值,否則父類無入值則會報錯。
this.z=z;
// this.show=() => console.log('this fn1',this.x,this.y,this.z);
}
// show = () => console.log('fn1',this.x,this.y,this.z);
}
a=new fn1(1,2,3)
console.log(a.show())
結果如下
class fn{ //定義類
constructor(x,y){
this.x=x; //定義屬性
this.y=y;
// this.show=() => console.log('this fn',this.x,this.y)
}
show = () => console.log('fn',this.x,this.y)
}
class fn1 extends fn{ //使用extends表示繼承
constructor(x,y,z){
super(x,y); //調用父類方法,必須傳入對應的值,否則父類無入值則會報錯。
this.z=z;
// this.show=() => console.log('this fn1',this.x,this.y,this.z);
}
// show = () => console.log('fn1',this.x,this.y,this.z);
}
a=new fn1(1,2,3)
console.log(a.show())
結果如下
總結
屬性和方法定義,不管是父類還是子類。都是優(yōu)先使用屬性,若兩個都是方法,則子類覆蓋父類 ,如果都是屬性,則是子類覆蓋父類,子類的優(yōu)先級是高于父類的
靜態(tài)屬性目前支持不完全
在方法前面加上static就是靜態(tài)方法了,此處的靜態(tài)方法是在類中進行調用的,而不是在實例中。
class fn{ //定義類
constructor(x,y){
this.x=x; //定義屬性
this.y=y;
}
static show = () => console.log('fn',this.x,this.y)
}
console.log(fn.show())
a=new fn(1,2)
console.log(a.show())
結果如下
雖然JavaScript和C和Java都有this,但JavaScript的表現(xiàn)是不同的
原因在于C,Java是靜態(tài)編譯語言,this是在編譯期間綁定的,而js是動態(tài)語言,是在運行期間鎖定的。
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: function(){
console.log(this.name)
console.log(this)
console.log('-----------------')
return function() {
console.log(this == global); //檢查其是否是全局的
return this.name;
}
}
}
method=school.getNamefunc //此屬性調用后返回的是函數(shù)的類型,并未調用外層函數(shù)
a=method() //調用外層函數(shù)
a() //調用內層函數(shù)
結果如下
上面的返回結果是其this本應該是school,卻被處理稱為了全局函數(shù)
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: function(){
console.log(this.name)
console.log(this)
console.log('-----------------')
return function() {
console.log(this == global); //檢查其是否是全局的
return this.name;
}
}
}
method=school.getNamefunc() //此處調用外層函數(shù)
a=method() //調用外層函數(shù)
結果如下
此處的結果是this仍然是全局屬性
分析上例
第三行的打印結果是true,則表明當前是global的作用于,因為調用這個返回的函數(shù)是直接調用的,這是一個普通函數(shù)調用,因此this是全局對象第四行undefined,就是因為this是global,所以沒name屬性
這就是函數(shù)調用的時候,調用方式不同,this對應的對象不同,它已經(jīng)不是C++,Java的指向實例本身了。
this的問題,這是歷史遺留問題,新版本只能兼容了。
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: function(){
console.log(this.name)
console.log(this)
console.log('-----------------')
return function(that) { //通過此處傳遞參數(shù)的方式改變
console.log(that == global); //檢查其是否是全局的
return that.name;
}
}
}
console.log(school.getNamefunc()(school))
結果如下
通過call將指定的this進行指定了。JavaScript中指代的是這個,其他的Java指定的不同,普通函數(shù)的調用和對象的調用是不同的,普通函數(shù)的調用中的thi指代的是全局變量,而在對象中調用,默認傳遞的值是this的本身
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: function(){
console.log(this.name)
console.log(this)
console.log('-----------------')
return function() {
console.log(this == global); //檢查其是否是全局的
return this.name;
}
}
}
var school1={
'name': 'test1'
}
method=school.getNamefunc() //此屬性調用后返回的是函數(shù)的類型,并未調用外層函數(shù)
console.log(method.call(school1)) //通過call將其this傳遞進去,
console.log('---------------')
console.log(method.call(school))
console.log('++++++++++++++++')
console.log(method.apply(school)) //通過apply,將其this傳遞過去
結果如下
相關源碼
apply和 call方法都是函數(shù)對象的方法
apply傳遞其他參數(shù)使用數(shù)組,call傳遞其他參數(shù)需要使用可變參數(shù)收集。相關情況如下
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: function(){
console.log(this.name)
console.log(this)
console.log('-----------------')
return function(x,y,z) {
console.log(this == global,x,y,z); //檢查其是否是全局的
return this.name;
}
}
}
method=school.getNamefunc() //此屬性調用后返回的是函數(shù)的類型,并未調用外層函數(shù)
console.log('---------------')
console.log(method.call(school,[1,2,3])) //此處傳地過去不會解構,是一個參數(shù)
console.log('++++++++++++++++')
console.log(method.apply(school,[1,2,3])) //通過apply,會解構,
結果如下
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: function(){
console.log(this.name)
console.log(this)
console.log('-----------------')
return function(x,y,z) {
console.log(this == global,x,y,z); //檢查其是否是全局的
return this.name;
}
}
}
method=school.getNamefunc() //此屬性調用后返回的是函數(shù)的類型,并未調用外層函數(shù)
console.log(method.bind(school)(1,2,3))
結果如下
bind 是會返回一個新函數(shù),其和偏函數(shù)相似
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: function(){
console.log(this.name)
console.log(this)
console.log('-----------------')
return (x,y,z) => {
console.log(this == global,x,y,z); //檢查其是否是全局的
return this.name;
}
}
}
school1={
name:'test1'
}
method=school.getNamefunc() //此屬性調用后返回的是函數(shù)的類型,并未調用外層函數(shù)
console.log(method(1,2,3))
結果如下
最外層使用箭頭函數(shù)的結果
var school= { //此處定義一個對象,其中包含name和getNamefunc兩個,其中name是屬性,getNamefunc是方法,其返回值是一個函數(shù)
name: 'test',
getNamefunc: () => {
console.log(this.name)
console.log(this)
console.log('-----------------')
return (x,y,z) => {
console.log(this == global,x,y,z); //檢查其是否是全局的
return this.name;
}
}
}
school1={
name:'test1'
}
method=school.getNamefunc() //此屬性調用后返回的是函數(shù)的類型,并未調用外層函數(shù)
console.log(method(1,2,3))
結果如下
因此,一般不建議最外層使用箭頭函數(shù)
Mixin 模式,及混合模式,這是一種不用繼承就能復用的技術,主要還是為了解決多重繼承的問題,多重繼承路徑是個問題
JS是基于對象的,類和對象都是對象模板
混合Mixin,指的是將一個對象的全部或者部分拷貝到另一個對象上去了,其實就是屬性,可以將多個類或者對象混合成一個類或者對象,任何一個對象都可以作為另一個對象的原型。
class test{
constructor(){
console.log('test',this)
if (typeof(this.show) !=='function') {
throw new ReferenceError('should define stringify.');
}
}
}
class test1 extends test{
constructor(x,y){
super();
this.x=x;
this.y=y;
}
show(){
return `test1 ${this.x} ${this.y}`;
}
}
p=new test1(1,2)
console.log(p.show())
結果如下
此處的核心是誰調用的問題,上述父類的this是子類的實例,而不是子類調用父類后父類形成的實例,因此這也是驗證通過的原因。
class test{
constructor(){
console.log('test',this)
if (typeof(this.show) !=='function') {
throw new ReferenceError('should define stringify.');
}
}
}
class test1 extends test{
constructor(x,y){
super();
this.x=x;
this.y=y;
}
show(){
return `test1 ${this.x} ${this.y}`;
}
}
class test2 extends test1 {
constructor(x,y,z) {
super(x,y);
this.z=z;
}
}
p=new test2(1,2)
console.log(p.show()) //此處自己本身沒有show,則通過調用父類的show來實現(xiàn),上述傳入的this 仍然是子類的實例,
結果如下
通過在test中使用函數(shù)并傳遞參數(shù)的方式將test1的相關屬性注入進去,相關代碼如下
初步改造結果如下
class test1{
constructor(x,y){
this.x=x;
this.y=y;
}
show(){
return `test1 ${this.x} ${this.y}`;
}
}
const test = function test(SUP) { //此函數(shù)的返回值是一個類,通過將類test1傳入其中進行相關的操作處理并進行輸出
return class extends SUP {
constructor(...args) {
super(...args);
console.log('test',this)
if (typeof(this.show) !=='function') {
throw new ReferenceError('should define stringify.');
}
}
}
}
class test2 extends test(test1){
constructor(x,y,z) {
super(x,y);
this.z=z;
}
}
p=new test2(1,2,3)
console.log(p.show())
結果如下
將上述函數(shù)修改為箭頭函數(shù)結果如下
class test1{
constructor(x,y){
this.x=x;
this.y=y;
}
show(){
return `test1 ${this.x} ${this.y}`;
}
}
const test = SUP=> class extends SUP {
constructor(...args) {
super(...args);
console.log('test',this)
if (typeof(this.show) !=='function') {
throw new ReferenceError('should define stringify.');
}
}
}
class test2 extends test(test1){
constructor(x,y,z) {
super(x,y);
this.z=z;
}
}
p=new test2(1,2,3)
console.log(p.show())
注意:
test(test1)這一步實際上是一個匿名箭頭函數(shù)的調用,返回一個新的類型,test2繼承自這個新的類型,增強了功能,react大量使用了這種Mixin技術。
try {
throw 1; // 拋出異常
} catch (error){ //此處不用指定異常類型,此處的error是上面的throw扔出來的
console.log(error,typeof(error));
}
拋出一個對象
try {
throw {}; // 拋出異常
} catch (error){ //此處不用指定異常類型,此處的error是上面的throw扔出來的
console.log(error,typeof(error));
}
結果如下
拋出一個函數(shù)
try {
throw () => console.log(2); // 拋出異常
} catch (error){ //此處不用指定異常類型,此處的error是上面的throw扔出來的
console.log(error,typeof(error));
}
結果如下
try {
throw Error('new Error'); // 拋出異常
} catch (error){ //此處不用指定異常類型,此處的error是上面的throw扔出來的
console.log(error,typeof(error));
}
結果如下
try?{
????throw?ReferenceError('new?Error')
}?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
????console.log(error,typeof(error));
};
結果如下
try?{
????throw?ReferenceError('new?Error')
}?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
????console.log(error,typeof(error)); //此處不影響下面的執(zhí)行
console.log(error.constructor); //此處的執(zhí)行結果是函數(shù)
};
結果如下
try?{
????throw?ReferenceError('new?Error')
}?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
????console.log(error,typeof(error)); //此處不影響下面的執(zhí)行
console.log(error.constructor.name); //獲取函數(shù)名稱
};
結果如下
try?{
????throw?null;
}?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
????console.log(error,typeof(error));
????console.log(error.constructor.name);?//一切皆函數(shù)
}?finally??{ //定義必須執(zhí)行的函數(shù)
????console.log('1325345234')
}
結果如下
常量的聲明和初始化時不能被分開的,常量只是對象的地址不能發(fā)生改變了,并不是其中的內容也不能改變了。
const l1=[1,2,3,4]
l1.pop() //l1雖然是一個常量,但其可以被修改
console.log(l1)
完全解構
const l1=[1,2,3,4]
const [a,b,c,d]=l1
console.log(a,b,c,d)
丟棄解構
const l1=[1,2,3,4]
const [a,b,,c,d]=l1
console.log(a,b,c,d)
結果如下
const l1=[1,2,3,4]
const [a]=l1
console.log(a)
結果如下
可變變量
const l1=[1,2,3,4]
const [a,...d]=l1
console.log(a,d)
結果如下
const l1=[1,2,3,4]
const [a,...d,e]=l1 //可變長必須放置在最后面
console.log(a,d,e)
默認值
const l1=[1,2,3,4]
const [x=10,,,,y=20]=l1 //能覆蓋的覆蓋,不能覆蓋的保持原值,先賦值,再覆蓋,
console.log(x,y)
const?arr?=?[1,[2,3],4];??//三個元素,嵌套解構
const?[a,[b,c],d]=arr;??
console.log(a,b,c,d);??//直接拆開?
const?[e,f]=arr;??//?只有兩
console.log(e,f);??//?第一個和第二個?
const?[g,h,i,j=18]=arr;??//?三個?加1?,則是對應的
console.log(g,h,i,j);
const??[k,...l]=arr;??//?此處會將后面兩個元素進行搬家
console.log(k,l);
結果如下
方法 | 描述 |
---|---|
push(...items) | 尾部追多個元素 |
pop() | 移除最后一個元素,并返回它 |
map | 引入處理函數(shù)來處理數(shù)組中的每一個元素,返回新的數(shù)組 |
filter | 引入處理函數(shù)處理數(shù)組中的每一個元素,此處理函數(shù)返回true的元素保留,否則該元素被過濾掉,保留的元素構成新的數(shù)組返回 |
foreach | 迭代所有元素,無返回值 |
const l1=[1,2,3,4]
l1.push([5,6,7,8])
l1.push(...['a','b','c'])
l1.push(9,10,11)
console.log(l1)
結果如下
const l1=[1,2,3,4]
l1.push([5,6,7,8])
l1.push(...['a','b','c'])
l1.push(9,10,11)
console.log(l1.pop())
console.log(l1.pop())
console.log(l1.pop())
console.log(l1)
結果如下
const abs = (x) => x**2
const l1=[1,2,3,4]
console.log(l1.map(abs))
結果如下
const abs = function (x) {
if (x%2==0) {
return true;
}
else {
return false;
}
}
const l1=[1,2,3,4]
console.log(l1.filter(abs))
結果如下
const l1=[1,2,3,4]
const newarr= l1.forEach(x=>x+10) //無返回值
console.log(newarr,l1)
結果如下
有一個數(shù)組const arr=[1,2,3,4,5];,要求計算出所有元素平方值是偶數(shù)且大于10的。
代碼一
const arr=[1,2,3,4,5];
console.log(arr.filter(x?=>?((x**2)%2==0?&&?(x**2)>10)))
代碼二,若平方是偶數(shù),則該數(shù)也應該是偶數(shù),則如下
const arr=[1,2,3,4,5];
console.log(arr.filter((x=> x%2==0 && x**2>10)))
代碼三,通過map來實現(xiàn)
const arr=[1,2,3,4,5];
console.log(Math.log2(((arr.filter(x=>x%2==0)).map(x=>x**2)).filter(x=>x>10)))
代碼四,求10的平方根,然后再進行相關比較
const arr=[1,2,3,4,5];
const cond=10
const cond1=Math.sqrt(cond)
console.log(arr.filter(x=>x%2==0 && x> cond1))
var??metadata=?{
????title:?"Seratchpad",
????translations?:[
????????{
????????locale:?"de",
????????localization_tags:?[],
????????last_edit:?"2019-01-01T08:11:11",
????????url:?"/de/docs/Tools/scratchpad",
????????title:?"JavaScript-Umgebung"
????????}
????],
????url:?"/en-US/docs/Tools/Scratchpad"?
}
var {title:enTitle,translations:[{title:?localeTitle}]?}=metadata; //: 后面的是重命名
console.log(enTitle)
console.log(localeTitle)
object 的靜態(tài)方法 | 描述 |
---|---|
object.keys(obj) | ES5開始支持,返回所有key |
object.values(obj) | 返回所有值,實驗階段,支持較差 |
object.entries(obj) | 返回所有值,試驗階段,支持較差 |
object.assign(target,...sources) | 使用多個source對象,來填充target對象,返回target對象 |
var??obj?=?{
????a:100,
????b:200,
????c:()=>{}
}
console.log(Object.keys(obj)) //返回所有的鍵
console.log(Object.values(obj)) //返回所有的值
console.log(Object.entries(obj))//返回所有的鍵和值
obj1={
d:300,
e:400,
}
let obj2=Object.assign(obj,obj1) //返回新的對象
console.log()
結果如下
ES6 之前,JS沒有出現(xiàn)模塊化系統(tǒng)
JS主要是在前端瀏覽器中使用,JS文件下載緩存到客戶端,在瀏覽器中執(zhí)行。
比如簡單的表達本地驗證,漂浮一個廣告。
服務器端使用ASP,JSP等動態(tài)網(wǎng)頁技術,將動態(tài)生成數(shù)據(jù)嵌入一個HTNL模板,里面夾雜著JS后使用<script>標簽,返回瀏覽器端。
這時候的JS知識一些簡單的函數(shù)和語句組合。
2005年后,隨著Google大量使用了AJAX技術后,可以一步請求服務器端數(shù)據(jù),帶來了前端交互的巨大變化,前端的功能需求越來越多,代碼也越來越多,隨著JS文件的增加,災難性的后果產生了,由于習慣了隨便寫,JS腳本中各種全局變量污染,函數(shù)名沖突,無法表達腳本之間的依賴關系。此時便有待模塊化的產生。
2008年V8引擎發(fā)布后,2009年誕生了nodejs,支持服務端JS編程,但沒有模塊化是不可以的,之后產生了commonjs規(guī)范。
commonjs 規(guī)范
使用全局require函數(shù)來導入模塊,模塊名就是文件名,使用exports導出變量
exports包含了所有需要導出的函數(shù)require會將exports中的所有函數(shù)遍歷出來即可進行相關的處理操作。
AMD規(guī)范
AMD (asynchronous module definition)異步模塊定義,使用異步方式加載模塊,模塊的加載不影響它后面語句的執(zhí)行,所有依這個模塊的語句,都需要定義在一個回調函數(shù)中,回調函數(shù)中使用模塊的變量和函數(shù),等模塊加載完成之后,這回調函數(shù)才執(zhí)行,就可以安全的使用模塊中的資源了。其實現(xiàn)就是AMD/requireJS.AMD雖然是異步,但是會預先加載和執(zhí)行。
CMD(Common Module Defintion),使用seajs,作者是淘寶前端玉伯,兼容并解決了requirejs的問題,CMD推崇as lazy as possible,盡可能的懶加載。
import語句,導入另一個模塊導出的綁定
export語句,從模塊中導出函數(shù),對象,值等,供其他模塊import導入
創(chuàng)建兩個文件
1.js和2.js
1.js中寫入如下數(shù)據(jù)
//導出默認類
export default ?class A {//此處設置默認導出,可以導出類,函數(shù),變量和常量
????constructor(x){
????????this.x=x;
????}
????show()?{
????????console.log(this.x)
????}????
}
//導出函數(shù)?
export?var foo =()?=>console.log('foo?function')
//導出變量?
export??const?CONST='aaa';
2.js中進行相關導入
如下
import {foo,CONST} from './1'; //此處若不指定./當前目錄。則默認是全局變量
import A from "./1";
let a=new A(10);
a.show();
foo();
console.log(CONST)
由于相關的引擎均不支持import 和export操作,因此需要通過相關的附加模塊來實現(xiàn)此種操作
上述中使用{}可以同時導入多個環(huán)境變量。
轉譯就是從一種語言代碼到另一個語言代碼,當然可以使從高版本轉譯到低版本的支持語句。
由于JS存在不同的版本,不同瀏覽器的兼容問題可通過transpiler轉譯工具進行解決,而babel就是其中的一種,官網(wǎng)如下
https://www.babeljs.cn
1 需要生成package.json文件,用于編譯使用,可通過npm init 進行初始化
生成文件如下
.npmrc文件,此文件可通過touch .npmrc創(chuàng)建
可以放置到npm目錄下的npmrc文件中。也可以放置到用戶家目錄中,也可以放置到項目根目錄中,此處放置到項目根目錄,如下
registry=http://registry.npm.taobao.org
如下
npm install babel-core babel-cli --save-dev
相關參數(shù)說明
--save-dev 說明
當你為你的模塊安裝一個依賴模塊時,正常情況下你得先安裝他們(在模塊根目錄下npm install mode-name),然后連同版本號手動將其添加到模塊配置文件package.json中的依賴中
--save 和--save-dev可以省略你手動修改package.json文件的步驟。
npm install mode-name --save 自動將模塊和版本號添加到dependencies部分,用于在打包至線上的依賴關系時使用
npm install mode-name --save-dev 自動將模塊和版本號添加到devdependencise部分查看package.json中的內容
項目根目錄中創(chuàng)建src和lib目錄
src是源碼目錄;
lib是目標目錄;
在目錄根目錄下創(chuàng)建.babelrc文件,json格式,其babelrc是和babel運行相關的
內容如下
{
"presets":["env"]
}
{
"name": "test",
"version": "1.0.0",
"description": "from test",
"main": "1.js",
"scripts": {
"build": "babel src -d lib"
},
"author": "test",
"license": "MIT",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3"
}
}
此處是scripts中的修改,其若目標為目錄,則為-d,若目標為文件,則為-o。
將1.js 和 2.js放置到src下
npm install babel-preset-env --save-dev
npm run build
轉換后的結果
運行如下
后期的通過webpack來實現(xiàn)所有的的聯(lián)動,自動化的打包操作全部進行處理。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。