GVKun编程网logo

javascript – 什么是FE开发人员?(js开发是什么意思)

16

本文将介绍javascript–什么是FE开发人员?的详细情况,特别是关于js开发是什么意思的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于20个前

本文将介绍javascript – 什么是FE开发人员?的详细情况,特别是关于js开发是什么意思的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于20 个前端开发人员必须知道的JavaScript 技巧、2013javascript开发人员调查结果、27个适用于JavaScript开发人员的神奇的VSCode工具、Flex:JavaScript写AIR程序>> 面向JavaScript开发人员的Adobe AIR与Dreamweaver的知识。

本文目录一览:

javascript – 什么是FE开发人员?(js开发是什么意思)

javascript – 什么是FE开发人员?(js开发是什么意思)

我刚刚得到一份工作机会,成为一名FE开发人员,但我从未听说过这个术语.强大的 HTML,CSS,Javascript,jQuery,XSL技能需要.

我认为自己精通所有这些领域,除了XSL,我从来没有听说过这个术语.任何人都可以启发我吗?

解决方法

前端开发

20 个前端开发人员必须知道的JavaScript 技巧

20 个前端开发人员必须知道的JavaScript 技巧

1、确定对象的数据类型

function myType(type) {
  return Object.prototype.toString.call(type).slice(8, -1);

使用Object.prototype.toString,通过传入不同类型的判断返回不同的判断函数,一行代码,简洁优雅灵活。

2、循环遍历数组map方法

const myMap = function (fn, context) {
  let arr = Array.prototype.slice.call(this);
  let resultArr = Array();
  for (let i = 0; i < arr.length; i++) {
    if (!arr.hasOwnProperty(i)) continue;
    resultArr[i] = fn.call(context, arr[i], i, this);
  }
  return resultArr;
};

Array.prototype.myMap = myMap;
let arr = [1, 2, 3];
console.log(arr.myMap((item) => item + 1)); // 2,3,4

值得注意的是,map第二个参数在第一个参数回调中指向this。如果第一个参数是箭头函数,则第二个 this 的设置无效,因为箭头函数的词法绑定。

3、循环遍历数组filter方法

const myFilter = function (fn, context) {
    let arr = Array.prototype.slice.call(this)
    let resultArr = []
    for (let i = 0; i < arr.length; i++) {
        if(!arr.hasOwnProperty(i)) continue;
         fn.call(context, arr[i], i, this) && resultArr.push(arr[i])
    }
    return resultArr
}
Array.prototype.myFilter = myFilter
let arr = [1, 2, 3]
console.log(arr.myFilter(item => item === 2)) // [2]

4、使用reduce实现数组filter方法

const myFilter2 = function (fn, context) {
    return this.reduce((total, current, index) => {
        return fn.call(context, current, index, this) ? [...total, current] : [...total]
    }, [])
}

5、遍历数组的some方法

const mySome = function (fn, context) {
  let arr = Array.prototype.slice.call(this);
  // The empty array returns false directly, and the every method of the array returns true conversely
  if (!arr.length) return false;
  for (let i = 0; i < arr.length; i++) {
    if (!arr.hasOwnProperty(i)) continue;
    let res = fn.call(context, arr[i], i, this);
    if (res) return true;
  }
  return false;
};

Array.prototype.mySome = mySome;

let arr = [1, 2, 3];
console.log(arr.mySome((item) => item === 2));

执行 some 的数组如果是空数组总是返回 false,而另一个数组的 every 方法中的数组如果是空数组总是返回 true。

6、通过循环实现数组的reduce方法

Array.prototype.myReduce = function (fn, initialValue) {
    let arr = Array.prototype.slice.call(this)
    let startItem
    let startIndex
    if (initialValue === undefined) {
        // Finds the element and subscript of the first non-empty (real) unit
        for (let i = 0; i < arr.length; i++) {
            if (!arr.hasOwnProperty(i)) continue
            startIndex = i
            startItem = arr[i]
            break
        }
    } else {
        startItem = initialValue
    }
    // The starting point for traversal is the real element after the real element found in the previous step
    // Each iteration skips the elements of the empty cell
    for (let i = ++startIndex || 0; i < arr.length; i++) {
        if (!arr.hasOwnProperty(i)) continue
        startItem = fn.call(null, startItem, arr[i], i, this)
    }
    return startItem
}

Array.prototype.myReduce = myReduce


let arr = [1, 2, 3]

console.log(arr.myReduce((acc, cur) => acc + cur)) // 6
console.log(arr.reduce((acc, cur) => acc + cur)) // 6

7、使用reduce实现数组的flat方法

// reduce implements array.prototype.flat, Array flat
const myFlat = function (depth = 1) {
    let arr = Array.prototype.slice.call(this)
    if (depth === 0) return arr
    return arr.reduce((total, current) => {
        if (Array.isArray(current)) {
            // You need to bind this with call, otherwise it points to the window
            return [...total, ...myFlat.call(current, depth-1)]
        } else {
            return [...total, current]
        }
    }, [])
}

Array.prototype.myFlat  = myFlat
let arr = [1, 2, [3, 4, [5, 6,[''a'',''b'',''c'',[''d'']], 7, 8], 9], 10, 11, 12, [13, 14]]

console.log(arr.myFlat())

因为myFlat依赖这个指向,所以需要在reduce遍历的时候指定myFlat的这个指向;否则默认指向window,会报错。

当数组的元素还是数组时,使用ES6的扩展运算符对其进行降维(ES5中可以使用concat方法)。但是数组元素内部可能有嵌套数组,所以需要递归调用selfFlat。

同时,原生的 Flat 方法支持一个深度参数来表示降维的深度。默认值为1,表示数组减少一维。

传递 Infinity 将传递的数组变成一维数组:

8、实现 ES6 类语法

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

Animal.staticFunc = function () {
    console.log(''staticFunc'')
}
Animal.prototype.sleep = function () {
    console.log(''animal is sleeping'')
}

//Parasitic combinatorial inheritance + inheritance between constructors
function Dog(name, color) {
    Animal.call(this, name)
    this.color = color
}

function inherit(subType, superType) {
    //Due to the nature of JavaScript reference types and functions passing by value, you cannot change the reference address of subType
    subType.prototype = Object.create(superType.prototype, {
        constructor: {
            enumerable: false,
            configurable: true,
            writable: true,
            // Points to subclasses, consistent with the default inheritance behavior
            value: subType
        }
    })
    //The child constructor inherits the parent constructor (the child inherits the static methods and static properties of the parent class)
    Object.setPrototypeOf(subType, superType)
}

inherit(Dog, Animal)

//You need to add the prototype method to Dog after inheritance, otherwise it will be overwritten
Dog.prototype.barking = function () {
    console.log(''wang!'')
}


let brownTeddy = new Dog(''teddy'', ''brown'')
Dog.staticFunc()
console.log(brownTeddy)
brownTeddy.sleep()
brownTeddy.barking()

Create 方法创建一个空 Object,并从 Object.create 方法的参数中继承这个空 Object。然后让子类的原型(subType)等于空对象,就可以实现子类的原型等于空对象,空对象等于父类的继承原型。

Object.create 支持第二个参数,它为生成的空对象定义属性和属性/访问器描述符。我们可以给这个空对象一个更符合默认继承行为的构造函数属性。它也是一个不能枚举的内部属性(Enumerable: False)。

ES6 类允许子类从父类继承静态方法和静态属性,而普通的寄生组合继承只能在实例之间实现。对于类到类的继承,需要定义额外的方法。

这里我们使用 Object.setProtoTypeof 将 superType 设置为 subType 的原型,从而能够从父类继承静态方法和静态属性。

9、Coriolization of functions

const display = (a, b, c, d, e, f) => [a, b, c, d, e, f];

/**
 * @description Currization of a function (How many times a currization function needs to be executed according to the number of parameters of the function before currization)
 * @param {function} fn -The Currified function
 */

function curry(fn) {
    if (fn.length <= 1) return fn;
    const generator = (...args) => {
        if (fn.length === args.length) {
            //Executes fn and returns the execution result
            return fn(...args)
        } else {
            return (...args2) => {
                //Return generator function
                return generator(...args, ...args2)
            }
        }
    }
    return generator
}

const curriedDisplay = curry(display);
console.log("curriedDisplay", curriedDisplay(1)(2)(3)(4)(5)(6));

Currization 是函数式编程中的一项重要技术,该技术将一个接受多个参数的函数转换为一系列接受一个参数的函数。

函数式编程 compose 另一个重要的功能,要能够进行函数组合,函数的组合只接受一个参数,所以,如果你必须接受多个函数的需求,并且需要使用 compose 函数组合,就需要使用 compose 的部分 curry 准备复合函数,让它总是只接受一个参数。

10、Function Corrification (placeholder support)

const curry3 = (fn, placeholder = "_") => {
    curry3.placeholder = placeholder
    if (fn.length <= 1) return fn;
    let argsList = []
    const generator = (...args) => {
        let currentPlaceholderIndex = -1 
        args.forEach(arg => {
            let placeholderIndex = argsList.findIndex(item => item === curry3.placeholder)
            if (placeholderIndex < 0) {
                currentPlaceholderIndex = argsList.push(arg) - 1
               
                // (1,''_'')(''_'',2)
            } else if (placeholderIndex !== currentPlaceholderIndex) {
                argsList[placeholderIndex] = arg
            } else { 
                argsList.push(arg)
            }
        })
        let realArgsList = argsList.filter(arg => arg !== curry3.placeholder) 
        if (realArgsList.length >= fn.length) {
            return fn(...argsList)
        } else {
            return generator
        }
    }

    return generator
}

const curriedDisplay3 = curry3(display);
console.log("curriedDisplay3", curriedDisplay3(''_'', 2)(1, ''_'', 4)(3, ''_'',)(''_'', 5)(6)(7, 8))

如果当前轮参数包含占位符,则将其放置在内部保存数组的末尾。当前轮的元素不填充当前轮参数的占位符,而只填充之前传入的占位符。

11、Fibonacci sequence and its optimization

const speed = function (fn, num) {
    console.time(''time'')
    let value = fn(num)
    console.timeEnd(''time'')
    console.log(`result:${value}`)
}

/**
 * @description Fibonacci numbers
 * @param {number} n -Number of positions
 * @return {number} The argument corresponds to a number in a sequence
 **/
let fibonacci = function (n) {
    if (n < 1) throw new Error(''Parameter is wrong'')
    if (n === 1 || n === 2) return 1
    return fibonacci(n - 1) + fibonacci(n - 2)
}

speed(fibonacci, 40)


//Memory function
const memory = function (fn) {
    let obj = {}
    return function (n) {
        if (obj[n] === undefined) obj[n] = fn(n)
        return obj[n]
    }
}
fibonacci = memory(fibonacci)

speed(fibonacci, 40)


/**
 * @description Fibonacci dynamic programming version (Optimal)
 **/
function fibonacci_DP(n) {
    let res = 1
    if (n === 1 && n === 2) return res
    n = n - 2
    let cur = 1
    let pre = 1
    while (n) {
        res = cur + pre
        pre = cur
        cur = res
        n--
    }
    return res
}

speed(fibonacci_DP, 40)

使用函数内存,我们可以为经常依赖先前结果的计算节省大量时间,例如斐波那契数列。缺点是闭包中的 obj 对象占用了额外的内存。

另外,动态规划的空间复杂度比前者低,也是比较推荐的方案。

12、实现绑定方法

const isComplexDataType = obj => (typeof obj === ''object'' || typeof obj === ''function'') && obj !== null

// Implement a simple bind
const myBind = function (bindTarget, ...args1) {
    if (typeof this !== ''function'') throw new TypeError(''Bind must be called on a function'')
    const originFunc = this
    const boundFunc = function (...args2) {
        // Calls using the new keyword return a new object
        if (new.target) {
            let res = originFunc.call(this, ...args1, ...args2)
            //If the constructor returns an object, that object is returned
            if (isComplexDataType(res)) return res
            //Otherwise, the newly created object is returned
            return this
        } else {
            return originFunc.call(bindTarget, ...args1, ...args2)
        }
    }
    if (originFunc.prototype) {
        boundFunc.prototype = originFunc.prototype
    }

    const desc = Object.getOwnPropertyDescriptors(originFunc)
    Object.defineProperties(boundFunc, {
        length: desc.length,
        name: Object.assign(desc.name, {
            value: `bound ${desc.name.value}`
        })
    })
    return boundFunc
}

实现函数的bind方法的核心使用调用绑定指向this,同时,考虑到其他情况如:
当bind返回的函数作为构造函数被new调用时,绑定值失效,变为new指定的对象。
定义绑定函数的长度和名称属性(不可枚举的属性)。

绑定函数的原型必须指向原函数的原型。

13、实现调用方法

const myCall = function (context, ...args) {
    let func = this
    context || (context = window)
    if (typeof func !== ''function'') throw new TypeError(''this is not function'')
    let caller = Symbol(''caller'')
    context[caller] = func
    let res = context[caller](...args)
    delete context[caller]
    return res
}

原理是将函数作为传入的上下文参数的属性执行。ES6 Symbol 类型用于防止属性冲突。

14、简单的CO模块

//Self-executing generator functions

const data = "{a:1,b:2}";
const data2 = "{c:3,d:4}";
const data3 = "{e:5,f:6}";

const api = function (data) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(data);
    }, 1000);
  });
};

function* func() {
  let res = yield api(data);
  console.log(res);
  let res2 = yield api(data2);
  console.log(res2);
  let res3 = yield api(data3);
  console.log(res3);
  console.log(res, res2, res3);
}

function makePromisify(source) {
  if (source.then && typeof source.then === "function") return source;
  return Promise.resolve(source);
}

function run(generatorFunc) {
  let it = generatorFunc();
  let result = it.next();

  return new Promise((resolve, reject) => {
    const next = function (result) {
      if (result.done) {
        return resolve(result.value);
      }
      result.value = makePromisify(result.value);
      result.value
        .then((res) => {
          let result = it.next(res);
          //Recursively execute the next function
          next(result);
        })
        .catch((err) => {
          reject(err);
        });
    };
    next(result);
  });
}

run(func);

run函数接受一个生成器函数,每次run函数包裹的生成器函数遇到yield关键字时停止,当yield后的promise解析成功时,自动调用next方法执行到下一个yield关键字。

最后,每次成功解析一个promise,都会解析下一个promise。

当所有的结果都解析成功后,所有解析的结果都会被打印出来,演变成今天最常用的 async/await 语法。

15、防抖功能

/**
 * @description debounce
 * @param {Function} func -Functions that need function stabilization
 * @param {Number} time -Delay time
 * @param {Options} options -Configuration items
 * @return {Function} -A function that has been shaken out
 **/

/**
 * @typedef {Object} Options -Configuration items
 * @property {Boolean} leading -Whether an extra trigger is required to start
 * @property {Boolean} trailing -Whether an additional trigger is required after the end
 * @property {this} context -this
 **/

const debounce = (func, time = 20, options = {
    leading: true,
    context: null
}) => {
    let timer;
    const _debounce = function (...args) {
        if (timer) {
            clearTimeout(timer)
        }
        if (options.leading && !timer) {
            timer = setTimeout(null, time)
            func.apply(options.context, args)
        }else{
            timer = setTimeout(() => {
                func.apply(options.context, args)
                timer = null
            }, time)
        }
    };
    
    _debounce.cancel = function () {
        clearTimeout(timer)
        timer = null
    };
    return _debounce
};

16、函数节流

/**
 * @description throttle
 * @param {Function} func -Functions that require function throttling
 * @param {Number} time -Delay time
 * @param {Options} options -Configuration items
 * @return {Function} -经过节流处理的函数
 **/

/**
 * @typedef {Object} Options -Configuration items
 * @property {Boolean} leading -Whether an extra trigger is required to start
 * @property {Boolean} trailing -Whether an additional trigger is required after the end
 * @property {this} context -this
 **/

const throttle = (func, time = 17, options = {
    // leading 和 trailing 无法同时为 false
    leading: true,
    trailing: false,
    context: null
}) => {
    let previous = new Date(0).getTime()
    let timer;
    const _throttle = function (...args) {
        let now = new Date().getTime();

        if (!options.leading) {
            if (timer) return
            timer = setTimeout(() => {
                timer = null
                func.apply(options.context, args)
            }, time)
        } else if (now - previous > time) {
            func.apply(options.context, args)
            previous = now
        } else if (options.trailing) {
            clearTimeout(timer)
            timer = setTimeout(() => {
                func.apply(options.context, args)
            }, time)
        }
    };
    _throttle.cancel = () => {
        previous = 0;
        clearTimeout(timer);
        timer = null
    };
    return _throttle
};

添加尾随选项以指示是否在序列结束时触发附加事件。

17、图片的延迟加载

// getBoundingClientRect lazy Load
let imgList1 = [...document.querySelectorAll(".get_bounding_rect")]
let num = imgList1.length

let lazyLoad1 = (function () {
    let count = 0
    return function () {
        let deleteIndexList = []
        imgList1.forEach((img,index) => {
            let rect = img.getBoundingClientRect()
            if (rect.top < window.innerHeight) {
                img.src = img.dataset.src
                // Add the image to the remove list after loading successfully
                deleteIndexList.push(index)
                count++
                if (count === num) {
                    //Unbind the Scroll event when all images are loaded
                    document.removeEventListener(''scroll'',lazyLoad1)
                }
            }
        })
        // Delete images that have been loaded
        imgList1 = imgList1.filter((_,index)=>!deleteIndexList.includes(index))

    }
})()

// The throttling function of throttle.js is referenced here
lazyLoad1 = proxy(lazyLoad1, 100)

document.addEventListener(''scroll'', lazyLoad1)
// Manually load the image once. Otherwise, the image on the first screen cannot be loaded without triggering scrolling
lazyLoad1()



// intersectionObserver lazy Load
let imgList2 = [...document.querySelectorAll(".intersection_observer")]

let lazyLoad2 = function () {
    // instantiation observer
    let observer = new IntersectionObserver(entries => {
        entries.forEach(entry => {
            if (entry.intersectionRatio > 0) {
                entry.target.src = entry.target.dataset.src
                observer.unobserve(entry.target)
            }
        })
    })
    imgList2.forEach(img => {
        observer.observe(img)
    })
}

lazyLoad2()

getBoundClientRect 的实现监听滚动事件(建议为监听事件添加节流)。图片加载完成后,会从 img 标签组成的 DOM 列表中删除。最后,加载监听器事件后,所有图像都需要解除绑定。

IntersectionObserver 是通过实例化一个intersectionObserver 并使其观察所有IMG 标签来实现的。

当img标签进入查看区域时,实例化时执行回调。同时,传入一个回调,保存实例来观察所有元素的某种状态,比如每个元素的边界,当前元素对应的DOM节点,当前元素进入查看区域的比例。

每当一个元素进入查看区域时,将真实图像分配给当前 IMG 标签,同时不观察它。

18、新关键字

const isComplexDataType = obj => (typeof obj === ''object'' || typeof obj === ''function'') && obj !== null

const myNew = function (fn, ...rest) {
    let instance = Object.create(fn.prototype)
    let res = fn.call(instance, ...rest)
    return isComplexDataType(res) ? res : instance
}

function Person(name, sex) {
    this.name = name
    this.sex = sex
}


let newPerson = new Person(''tony'', ''woman'')
let myNewPerson = myNew(Person, ''tony1'', ''man'')

console.log(newPerson)
console.log(myNewPerson)

19、实现对象分配

"use strict" 

const isComplexDataType = obj => (typeof obj === ''object'' || typeof obj === ''function'') && obj !== null


const myAssign = function (target, ...source) {
    if (target == null) throw new TypeError(''Cannot convert undefined or null to object'')
    return source.reduce((acc, cur) => {
        isComplexDataType(acc) || (acc = new Object(acc)); 
        if (cur == null) return acc; 
        [...Object.keys(cur), ...Object.getOwnPropertySymbols(cur)].forEach(key => {
            acc[key] = cur[key]
        })
        return acc
    }, target)
}

Object.myAssign = myAssign


let target = {
    a: 1,
    b: 1
}

let obj1 = {
    a: 2,
    b: 2,
    c: undefined
}

let obj2 = {
    a: 3,
    b: 3,
    [Symbol("a")]: 3,
    d: null
}

console.log(Object.myAssign(target, obj1, obj2))
console.log(Object.myAssign("abd", null, undefined))

20、实例化

const myInstanceof = function (left, right) {
    let proto = Object.getPrototypeOf(left)
    while (true) {
        if (proto == null) return false
        if (proto === right.prototype) {
            return true
        }
        proto = Object.getPrototypeOf(proto)
    }
}

console.log(myInstanceof({}, Array))

总结

以上就是我跟大家分享的20 个出色实用的JavaScript技巧,可帮助您编写更好、更高效的代码。想要了解更多欢迎前往公众号:WEB前端开发社区,每日干货分享

2013javascript开发人员调查结果

2013javascript开发人员调查结果

JavaScript开发人员调查现在已经结束,一如既往社区对结果进行了进一步分析:

  • 总结(汉语)

  • 原始数据(电子表格)

  • 2012年结果

51%的被参与者写客户端代码,而28%的人说他们编写服务器端代码。去年客户端的占比是98%,所以我猜想,DailyJS起到了一定的积极作用,但有趣的是服务器端开发怎么发展的如此迅猛。

当被问到在哪里写javascript时,54%的人回答“工作”,45%的人回答“项目”。这可能一个人同时回答两种情况——我发现这对程序员是通用的,无论是专业人士还是业余爱好者。

大多数的参与者编写JavaScript已经有三到五年(34%)。我不禁觉得这得益于Node的增长——人们在经历使用其他的语言进行后台开发后,重新发现JavaScript的魅力,或者得益于前端框架的成长,如AngularJS和Backbone.js。我无法想象设计人员不具备JavaScript技巧。

78%的参与者说他们没有使用可以编译成JavaScript的语言(类似coffeescript)。我已经注意到Node社区的一些颇具影响力的成员对这些语言的声音,所以似乎看起来参与者同意。我在博客中尽量保持关于这些语言的一些报道,但总的来说重点是JavaScript。与其他语言不同,使用tab可以节省一点点尺寸,所以我不太介意使用哪种方法。

CoffeeScript 是最流行的“编译(conpile-to)”语言(64%),TypeScript从去年开始初见端倪(19%)。

代码的样式问题很混乱,结尾的分号,逗号和方法保留一个空格是最受欢迎的选择。有趣的是9%的人使用tab而11%的人使用空格。客户端开发者好像偏爱于四个空格,然而仅有8%的人选择此项。

测试的结果太好笑了:

  • 是:25%

  • 否:26%

  • 有时(Sometimes)/不总是(not enough)/不太多

我喜欢你的诚实,“不总是”可能只是谦虚,所以我意识到“很多参与者仅写些例子,但他们觉得自己可以做的更好”。

Jasmine非常流行,大约占30%。我始终认为tap是最好的方法,但它只占2%。Mocha表现很好,占到27%,QUnit下降到16%。我认为这很能证明参加调查的很大一部分是Node开发者,但也可能是人们看到Mocha作为一个浏览器/Node模块的魅力,而且QUnit很多时候仅配合jQuery使用(这不一定是真的)。

CI服务?36%的人回答是。Node绝对是CI服务的好基友——我最近开始用TeamCity的服务器做objective - c项目并且这是令人吃惊的困难。和搭配Travis CI的开源Node项目比起来,这简直让人可笑。然而,Jenkins是最流行的CI服务(44%),TeamCity斩获(13%),所以也许人们发现跟踪客户端或Node检测很容易,在使用多种语言现有企业CI服务的帮助下。

原来人们喜欢AMD!然而如果我们把CommonJS的结果分开来看,我们发现17%的人使用CommonJS而12%的人使用Browserify。很长一段时间我提倡CommonJS,但Browserify的理论很有说服力……

当看到AngularJS和Backbone.js在客户端框架中各占25%时,我很吃惊,他们有各自的内涵,但我不自觉的认为他们用来解决不同的问题。

一般常识认为支持IE似乎应该从IE 8开始(37%)。我猜那是公司的支持要求,这是已经存在十年之久的web开发人员心中的阵痛。

你使用ES6的特性吗?85%的人回答“不”,所以不过你没有使用,其实你一点也不糟糕。我可能仅仅写DailyJS文章的时候会用到,但我们将会在明年看到这种情况开始增长。

PHP是最受欢迎的主要开发语言(24%),c#有17%。你好.NET成员!

感谢大家参加调查!如果你可以用这些数据做一些很酷的事,我很想听听。


27个适用于JavaScript开发人员的神奇的VSCode工具

27个适用于JavaScript开发人员的神奇的VSCode工具

visual studio code(也称为vscode)是一种轻量级但功能强大的跨平台源代码编辑器, 借助对typescript 和chrome调试器等开发工具的内置支持,越来越多的开发都都喜欢使用它。

27个适用于JavaScript开发人员的神奇的VSCode工具

如果你正在寻找更多的好用的 VSCode 工具,那么这篇或许能够帮助你。以下是 2019年为 JS 开发者提供的27个不可思议的VSCode工具。

1. Project Snippets (代码片段)

project snippets,这是我最喜欢的一个工具,它来自于 VSCode 中内置的原始用户代码片段。 该特性允许你创建自己的代码段,以便在整个项目中重用。

但是**“重用”**它们到底意味着什么?

如果咱们经常要重复写下面这样的样板文件:

立即学习“Java免费学习笔记(深入)”;

import { useReducer } from &#39;react&#39;

const initialState = {
  //
}

const reducer = (state, action) => {
  switch (action.type) {
    default:
      return state
  }
}

const useSomeHook = () => {
  const [state, dispatch] = useReducer(reducer, initialState)
  return {
    ...state,
  }
}

export default useSomeHook
登录后复制

实际上,咱们可以直接将上面的代码放到的用户代码片段中,因此不必写出(或复制和粘贴)整个代码片段,只需键入一个自定义前缀来生成配置的代码片段即可。

打开 VsCode,然后选择 文件 >首选项 > 用户代码片段,则可以选择通过单击 ''新建全局代码片段文件''来创建新的全局代码片段。

例如,要为 TypeScript React 项目创建自己的代码片段文件,可以单击新建全局代码片段文件,输入 typescriptreact.json。它将引导咱们访问一个新创建的.json文件,可以使用该文件来构建使用TypeScript 的 React 应用程序。

例如,要从上面的代码示例创建一个用户片段,可以这样做:

{
  "const initialState = {}; const reducer = (state, action)": {
    "prefix": "rsr",
    "body": [
      "const initialState = {",
      "  //$1",
      "}",
      "",
      "const reducer = (state, action) => {",
      "  switch (action.type) {",
      "    default:",
      "      return state",
      "  }",
      "}"
    ]
  }
}
登录后复制

有了它,咱们可以创建一个以.tsx结尾的新TypeScript文件,在新创建的文件输入rsr,然后按回车或 tab 键 VSCode 就会帮咱们生成代码片段内容。

const initialState = {
  //
}

const reducer = (state, action) => {
  switch (action.type) {
    default:
      return state
  }
}
登录后复制

全局用户代码片段的问题是,它将贯穿咱们所有项目(在某些情况下,这对于一般的代码片段来说是非常强大的)。

一些项目将以不同的方式配置,当需要区分特定的用例时,用于配置代码片段的全局文件就成了一个问题。

例如,当每个项目的项目结构不同时

{
  "import Link from components/common/Link": {
    "prefix": "gcl",
    "body": "import Link from &#39;components/common/Link&#39;"
  },
  "border test": {
    "prefix": "b1",
    "body": "border: &#39;1px solid red&#39;,"
  },
  "border test2": {
    "prefix": "b2",
    "body": "border: &#39;1px solid green&#39;,"
  },
  "border test3": {
    "prefix": "b3",
    "body": "border: &#39;1px solid magenta&#39;,"
  }
}
登录后复制

这对于具有特定file/folder结构的项目可能就足够了,但是如果咱们正在处理另一个项目,其中 Link 组件具有类似components/Link的路径,该怎么办?

请注意这三个border tests是如何将它们的值用单引号括起来的:border: ''1px solid red''。

这在 JS 中是完全有效的,但是如果使用 styled-components 作为项目的样式解决方案呢?该语法不再适用于该工作区,因为 styled components使用普通的CSS语法

这就是 project snippets 的亮点所在。

Project snippets使咱们可以声明项目/工作区级别的代码段,让当前项目代码段不会与其它项目冲突也不会污染其他项目。

2. Better Comments(更加人性化的注释)

如果喜欢在代码中编写注释,那么有时你可能会发现搜索您以前编写的特定注释的位置是令人沮丧的,因为代码可能会变得有些拥挤。

有了 Better Comments,可以通过引入彩色注释使注释更加明显。

1.jpg

3. Bracket Pair Colorizer (标签匹配 括号匹配插件)

第一次看到Bracket Pair Colorizer的屏幕截图时,我第一时间入安装使用了。

1.png

4. Material Theme

Material Theme是一个史诗主题,可以直接安装到VSCode中,安装后代码看起来像这样:

1.gif

5. @typescript-eslint/parser

如果你是一个TypeScript用户,应该开始考虑将你的 TSLint 配置转移到ESLint + TypeScript上,TSLint 背后的支持者已经宣布计划在今年的某个时候弃用 TSLint。

项目正逐步采用@typescript-eslint/parser和相关包,以确保其项目的前瞻性设置。

咱们仍然能够利用大部分ESLint的规则和兼容性与更漂亮使用新的设置。

6. Stylelint

对我来说,出于以下几个原因,stylelint 在我所有的项目中都是必须的:

  1. 它有助于避免错误。

  2. 它加强了CSS中的样式约定。

  3. 它与Prettier支持并驾齐驱。

  4. 它支持 CSS/SCSS/Sass/Less。

  5. 它支持社区编写的插件。

4.jpg

7. Markdownlint + docsify

markdown 爱好者一定要试试 vscode 上的 markdownlint 扩展,会用绿色波浪线给你提示出 N 多不符合书写规范的地方,比如:

  • 标题下面必须是个空行

  • 代码段必须加上类型

  • 文中不能出现
    这种html标号

  • URL必须用< >扩起来

同时也可以配合安装 docsify,因为它支持Markdown和每个项目的其他增强。

8. TODO Highlight

如果习惯在应用程序代码中编写待办事项的开发者,可以安装 TODO Highlight 这样的扩展名对于突出显示整个项目中设置的待办事项非常有用。

5.jpg

9. Import Cost

Import Cost 可以显示咱们在VS代码编辑器中导入的程序包的大小。

6.gif

10. Highlight Matching Tag

有时,试图匹配标签的结束地方会令人沮丧,这时 Highlight Matching Tag 就派上用场了

7.gif

11. vscode-spotify

程序员经常边听歌边打代码,有时候写到一半,歌太难听,想切换,得切到音乐播放器,然后在回到 VsCdoe 界面,有点麻烦。

这就是 vscode-spotify 用武功之地,因为它可以在VSCode内直接使用音乐播放器。

有了这个扩展,各位就可以在状态栏中看到当前播放的歌曲,可以通过热键在歌曲之间切换,也可以点击按钮来控制音乐播放器等等。

8.jpg

12. GraphQL for VSCode

GraphQL一直在发展,咱们经常可以在 JS 社区中看到它的身影。因此,最好开始考虑在 VSCode中安装 GraphQL for VSCode。

9.jpg

13. Indent-Rainbow

Indent-Rainbow 会给缩进添加一种颜色,让你更加直观的看到代码层次。

10.jpg

14. Color Highlight

Color Highlight 可以在代码中突出显示颜色,如下所示:

11.jpg

15. Color Picker

Color Picker 是一个 VSCode 扩展,它为咱们提供了一个图形用户界面,用来选择和生成颜色代码,如 CSS 颜色符号。

12.gif

16. REST Client

第一次看到 REST Client 并尝试它时,与现有的软件(如Postman)相比,它似乎不是一个非常有用的工具。

但是,对 REST Client 扩展的用法了解越多,就会意识到它对开发工具的影响有多大,尤其是在测试API 时。

只需要创建一个新文件写入下面这一行:

https://google.com
登录后复制

然后转到命令面板(CTRL + SHIFT + P),单击Rest Client: Send request,它会在一瞬间弹出一个包含请求响应详细信息的新选项卡,非常有用:

13.jpg

甚至还可以传递参数,或将请求体数据请求到POST,而下面仅需几行代码:

POST https://test.someapi.com/v1/account/user/login/
Content-Type: application/json

{ "email": "someemail@gmail.com", "password": 1 }
登录后复制

就会发送POST请求,参数为 { "email": "someemail@gmail.com", "password": 1 }。

17. Settings Sync

vscode上有各种各样不同的插件,如果要在不同的电脑上使用 vscode 配置是件比较麻烦的事情,使用 Settings Sync 将 vscode 配置备份起来,当需要在其他电脑使用  vscode  时只需下载备份的配置就可以了。

咱们只需要一个 GitHub 帐户,并且每次要保存配置(包括按键绑定,代码片段,扩展名等)时,只需按SHIFT + ALT + U将私有设置上传到 GitHub 帐户即可。 然后,下次登录或重新格式化为另一台计算机时,可以按SHIFT + ALT + D组合键立即下载配置。

18. Todo Tree

Todo Tree 将帮助咱们找到在整个应用程序代码中创建的所有待办事项。它将把它们放到一个单独的树中,还可以在面板的左侧同时查看它们

14.jpg

19. Toggle Quotes

Toggle Quotes是一个有趣的实用工具扩展,它允许咱们在引号之间进行切换。当需要在使用字符串插入时切换到反引号时,它就派上用场了。

15.gif

20. Better Align

Better Align 对齐赋值符号和注释。要使用它,将光标放在想要对齐的代码中,使用CTRL + SHIFT + P打开命令面板(或者使用自定义快捷方式打开命令面板),然后调用Align 命令。

16.gif

21. Auto Close Tag

Auto Close Tag自动闭合html标签。

17.gif

22. Sort Lines

Sort lines 可以帮助咱们排序选中行。

18.gif

23. VSCode Google Translate

如果是参与多语言开发的项目,VSCode Google Translate 可以帮助咱们快速切换语言。

19.gif

24. Prettier

Prettier是VSCode的扩展,可自动格式化JavaScript/TypeScript 等等,使代码更漂亮。

20.jpg

25. Material Icon Theme

与其他图标主题相比,我更喜欢 Material Icon Theme,因为文件类型更为明显,尤其是在使用深色主题。

2.jpg

26. IntelliSense for CSS Class Names in HTML

IntelliSense for CSS Class Names in HTML,基于在工作空间中找到的定义性,并提供了CSS 类名补全。

27. Path Intellisense

Path Intellisense 自动路劲补全。

22.gif

原文地址:https://dev.to/jsmanifest/26-miraculous-vs-code-tools-for-javascript-developers-in-2019-50gg

为了保证的可读性,本文采用意译而非直译。

推荐教程:vscode基础教程

以上就是27个适用于JavaScript开发人员的神奇的VSCode工具的详细内容,更多请关注php中文网其它相关文章!

Flex:JavaScript写AIR程序>> 面向JavaScript开发人员的Adobe AIR与Dreamweaver

Flex:JavaScript写AIR程序>> 面向JavaScript开发人员的Adobe AIR与Dreamweaver

看了一遍文章挺有意思的,Dreamweaver 用JavaScript写Adobe AIR程序。

http://cw2cw.blog.163.com/blog/static/1660389920101235157994/

应用:

http://code.google.com/p/readair/downloads/detail?name=ReadAir.0.3.Source.zip&can=2&q=

我们今天的关于javascript – 什么是FE开发人员?js开发是什么意思的分享已经告一段落,感谢您的关注,如果您想了解更多关于20 个前端开发人员必须知道的JavaScript 技巧、2013javascript开发人员调查结果、27个适用于JavaScript开发人员的神奇的VSCode工具、Flex:JavaScript写AIR程序>> 面向JavaScript开发人员的Adobe AIR与Dreamweaver的相关信息,请在本站查询。

本文标签: