zoukankan      html  css  js  c++  java
  • JS之函数

    function add(x,y){        //函数,声明提升,可以在函数定义之前调用
        return x+y
    }
    
    var add = function (x,y){ //函数表达式,不会提升声明
        return x+y
    }
    
    var sum1 = function _sum(x){ //函数表达式不省略名字,也只能在函数内部使用
        if (x==1)               // if后不能加分号
        return 1;
        return x+_sum(x-1);
    }
    // console.log(sum(5))
    
    const counter = function (){
        let c = 0
        return function (){
            return ++c
        }
    }
    c = counter()
    
    arr = new Array(1,2,3,4,5)
    var map = function map(arr,fn){
        let newarry = []
        for (i in arr)
            newarry[i] = fn(arr[i])
        return newarry
    }
    
    
    // console.log(map(arr,function(x) {return ++x}))//匿名函数
    // console.log(map(arr,x=>++x)) //箭头函数,就是匿名函数,更加简洁
    
    var map = function * (arr,fn){
        for(i in arr)
            yield fn(arr[i])
    
    }
    let newarr = map(arr,x=>++x)
    /*
    箭头函数:如果一个函数没有参数使用();
    如果只有一个参数,可以省略小括号
    多个参数不能省略小括号,且使用逗号间隔
    箭头函数返回值:如果函数体部分有多行,就需要使用{},如果有返回值使用return
    如果只有一行语句,可以同时省略大括号和return,有return必有{}
    */
    
    
    const sum = function (...args){ //[1,2,3]
        let result = 0
        console.log(arguments) //所有的参数,包括位置参数
        for (let x in args){  //[[1,2,3]]
            // console.log(args[x],'~~~~~~~~~`')
            result += args[x]
        }
        return result
    }
    // console.log(sum(...[1,2,3,4,5]))
    // console.log(100+[1,2,3,4]) //1001,2,3,4
    
    const rvalue = (x,y) => {return x,y}
    console.log(rvalue(5,6))
    /*
    表达式的值
    赋值表达式的值:等号右边的值
    逗号表达式的值:最后一个表达式的值
    */

    1.1es6之前的类定义

    定义一个函数(构造器对象)函数首字母大写
    使用this定义属性
    使用new和构造器创建一个对象
    本质还是一个function //[Function: Point]
    function Point(x,y){  //Es6之前
        this.x = x
        this.y = y
        this.show = ()=>console.log(this.x,this.y)
        
    }
    console.log(Point)
    p1 = new Point(3,4)
    console.log(p1)
    
    function Point3d(x,y,z){
        Point.call(this,x,y)  //继承
        this.z = z
        console.log('this is Poind3d')
    }
    p2 = new Point3d(1,2,3)
    console.log(p2)
    p2.show()
    注意:如果不使用new关键字,就是一次普通的函数调用,this不代表实例

     1.2 es6中class的定义

    1.从es6开始,新提供了class关键字,是的创建对象更加简单,清晰
    2.类定义使用class关键字,创建的本质还是函数,是一个特殊的哈数
    3.一个类只能拥有一个constructor的构造器方法,如果没有显示的定义一个构造方法,则会添加一个默认的构造方法
    4.继承使用extends关键字
    5.一个构造器可以使用super关键字来调用一个父类的构造函数
    6.类没有私有属性 

    1.2.1 类的继承从父类全部继承

    class Poing{
        constructor(x,y){
            this.x = x
            this.y = y
        }
        show()
        {   console.log(this) //实例p1
            console.log(this,this.x,this.y)
        }
    }
    
    p1 = new Poing(4,5)
    console.log(p1)
    
    class Poing3d  extends Poing{  //继承
        constructor(x,y,z){
            super(x,y)
            this.z = z 
        }
    }
    p2 = new Poing3d(7,8,9)
    console.log(p2)
    p2.show()

    1.2.2 es6静态属性

    class Poing{
        constructor(x,y){
            this.x = x
            this.y = y
        }
        show()
        {   console.log(this) //实例p1
            console.log(this,this.x,this.y)
        }
    }
    
    p1 = new Poing(4,5)
    console.log(p1)
    
    class Poing3d  extends Poing{  //继承
        constructor(x,y,z){
            super(x,y)
            this.z = z 
        }
        static set(){
            console.log('set')
        }
    }
    p2 = new Poing3d(7,8,9)
    console.log(p2)
    Poing3d.set()
    p2.constructor.set() //实例只能通过这种方式访问静态属性

     2.1   this出现的问题整理与总结

    c++。java是静态编译型语言,this是编译期间绑定,js是动态语言,运行期绑定
    var school = {
        name:'python',
        getNameFunc:function(){
            console.log(this.name)
            console.log(this)
            return function (){
                console.log(this === global)
                return this.name
            }
        }
    }
    函数执行期间会开启新的上下文环境executioncontext,创建this属性,但是this是什么就要看函数怎么调用
    1.myfunction(1,2,3)普通函数的调用方式,this指向全局对象,全局对象是nodejs的global或者浏览器的windows
    2.myobject.myfunction(1,2,3)对象的调用方式,this指向包含该方法的对象
    3.call和apply方法调用,需要看第一个参数是谁

    2.1.1  this的显示传入

    var school = {
        name:'python',
        getNameFunc:function(){
            console.log(this.name)
            console.log(this)
            return function (that){  //普通函数这块传入一个参数
                console.log(that === global)
                return that.name
            }
        }
    }
    
    console.log(school.getNameFunc()(school))
    es3
    apply.call方法都是函数对象的方法,第一个参数都是传入对象引入的 apply传入其他参数需要使用数组 call传入其他参数需要使用可变参数收集
    var school = {
        name:'python',
        getNameFunc:function(){
            console.log(this.name)
            console.log(this)
            return function (){  //普通函数这块传入一个参数
                console.log(this === global)
                return this.name
            }
        }
    }
    
    console.log(school.getNameFunc().apply(school))
    console.log(school.getNameFunc().call(school))

      2.1.2 bind es5,最常用的方式解决this问题

    var school = {
        name:'python',
        getNameFunc:function(x,y){
            console.log(1,this)
            console.log(2,this.x,this.y)
            return function(){
                console.log(3,this === global)
                return this.name
            }
        }
    }
    
    // console.log(school.getNameFunc().bind(school)) //错误用法
    var func = school.getNameFunc() //等同于上条调用
    var boundfunc = func.bind(school) //bind返回i虚拟的函数,先为函数绑定this,调用时直接用
    console.log(boundfunc())

     2.1.3  箭头函数解决this问题 es6新技术,不需要兼容this问题

    var school = {
        name:'python',
        getNameFunc:function(x,y){
            console.log(1,this)
            console.log(2,this.x,this.y)
            return ()=>{
                console.log(3,this === global)
                return this.name
            }
        }
    }
    
    // console.log(school.getNameFunc().bind(school)) //错误用法
    var func = school.getNameFunc() //等同于上条调用
    var boundfunc = func.bind(school) //bind返回i虚拟的函数,先为函数绑定this,调用时直接用
    console.log(boundfunc())

     3.1高阶对象MIXIN模式

    /*
    四种类的定义以及转换
    */
    class A{}
    const B = class {
        constructor(x){
            console.log(x)
        }
    }
    const C = class extends B{}
    
    
    const D = Sup => class extends Sup{}//用一个函数来返回类的定义
    cls = D(B)  //返回类定义
    d = new cls(300)

     代码改造前后

    class Serialization {
        constructor(){
            console.log('serialization constructor')
            if (typeof this.stringify!=='function'){
                throw new ReferenceError('show define stringify')
            }
        }
    }
    
    
    class Point extends Serialization{
        constructor(x,y){
            console.log('Point constructor')
            super()
            this.x = x
            this.y = y
        }
        stringify(){
            console.log(`Point <${this.x}:${this.y}>`)
        }
    }
    
    
    class Point3D extends Point {
        constructor(x,y,z){
            super(x,y)
            this.z = z
        }
    
    }
    p = new Point(2,3)
    pd = new Point3D(5,6)
    console.log('~~~~~~~~~~~~~~~~~~~~')
    p.stringify()
    pd.stringify()

     改造后

    var serialization = Sup =>class extends Sup {
        constructor(...args){
            console.log('serialization constructor')
            super(...args)
            if (typeof this.stringify!=='function'){
                throw new ReferenceError('show define stringify')
            }
        }
    }
    
    
    class Point  {
        constructor(x,y){
            console.log('Point constructor')
            this.x = x
            this.y = y
        }
        stringify(){
            console.log(`Point <${this.x}:${this.y}>`)
        }
    }
    
    
    class Point3D extends serialization(Point) {
        constructor(x,y,z){
            super(x,y)
            this.z = z
        }
    
    }
    pd = new Point3D(5,6,6)
    console.log(pd)

     js foreach 

    var metadata ={
        title:'python',
        translations:[
            {
                locale:'de',
                url:{}
            }
        ]
    }
    console.log(Object.keys(metadata))
    console.log(Object.values(metadata))
    console.log(Object.entries(metadata))
    var copy = Object.assign({},metadata,{school:"mage"},{url:null})
    console.log(copy)
    
    
    
    const arr = [1,2,3,4,5]
    newarr = []
    arr.forEach(
        function(x){
            newarr.push(x)
        }
    )
    console.log(newarr)

    export default

    使用export default时,对应的import语句不需要使用大括号;不使用export default时,对应的import语句需要使用大括号。
    
    export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export default命令只能使用一次。import命令后面才不用加大括号,因为只可能对应一个方法。
    
    本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字
    本文为原创文章,转载请标明出处
  • 相关阅读:
    基因id转换
    Trinity的分步运行
    免费的稳定的SVN托管的服务器
    游戏化
    一个华裔男孩在美国的成长之路
    你懂USB和Type-C吗
    ios调试小技巧
    swift开发笔记19
    iOS 3DTouch应用
    iCloud实现APP多设备数据同步
  • 原文地址:https://www.cnblogs.com/harden13/p/9262957.html
Copyright © 2011-2022 走看看