分享
是一种美德

web页面跳转微信小程序

wangtong阅读(814)

现在微信开放程度比较宽松了,所以web页面跳转小程序需求很大,接下来咱们看看怎么实现:

 

1、需要引入微信jssdk:http://res.wx.qq.com/open/js/jweixin-1.6.0.js(支持https)

需要使用到js-sdk-1.6.0的版本才有支持

2、在页面中配置信息:

   wx.config({
            // debug: true, // 调试时可开启
            appId: '小程序 AppID', // <!-- replace -->
            timestamp: 0, // 必填,填任意数字即可
            nonceStr: 'nonceStr', // 必填,填任意非空字符串即可
            signature: 'signature', // 必填,填任意非空字符串即可
            jsApiList: ['chooseImage'], // 必填,随意一个接口即可 
            openTagList:['wx-open-launch-weapp'], // 填入打开小程序的开放标签名
          })

3、html添加微信支持的开放标签,就是config中openTagList 支持的

<div class="content">

                <wx-open-launch-weapp id="launch-btn"  username="小程序的原始ID(gh_****)" path="落地页">

                    <template>

                        <style>

                            .abtn {

                                width: 100%;

                                height: 381px;

                                display: block;

                                margin: 0 auto;

                            }

                        </style>

                        <button>跳转小程序</button>

                        <div class="abtn"></div>

                    </template> 

                </wx-open-launch-weapp>

        </div>

预览一下:

 

参考资料:

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html

 

欢迎大家关注公众号:

web页面-js-获取用户信息

wangtong阅读(286)

web页面获取微信用户的信息,其实主要就是根据code去根据微信的接口去获取,下来先讲一下如何获取code:

现在我就用我实际场景放代码了,

1、url方法:

//因为我这个链接别的地方会有用到,所以我在这单独定义一个方法返回固定的url
function getUrlLink(){

    var urllink = 'url'

    return urllink

}

2、获取微信code:

function getBaseInfos(){

    var urllink = getUrlLink()

    var url_code = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx599ae3b5b1543a1a&redirect_uri="+urllink+"&response_type=code&scope=snsapi_base&state=1&connect_redirect=1#wechat_redirect";

    

    window.location.href = url_code;//打开这个链接,你的url后面就会跟上code的参数

    

}

3、截取url中的code:

function getUrlValueByName(name){//这个是来截取code

    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");  

    var r = window.location.search.substr(1).match(reg);  

    if (r != null) return unescape(r[2]); return null;  

    

}
3、得到code后去请求后台接口获取用户信息
var code = getUrlValueByName('code')

var data = {}

data.code = code

is_report(data)//这个方法就是请求后台接口了,ajax
4、ajax方法:
function is_report(data){

    $.ajax({

        //请求方式

        type : "POST",

        //请求的媒体类型

        contentType: "application/json;charset=UTF-8",

        //请求地址

        url : "接口地址",

        //数据,json字符串

        data : JSON.stringify(data),

        //请求成功

        success : function(result) {

            console.log(result);

            if(result.code === 200){

            }

        },

        //请求失败,包含具体的错误信息

        error : function(e){

            console.log(e.status);

            console.log(e.responseText);

        }

    });

}
参考资料:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0

欢迎大家关注公众号:

js判断页面在移动端微信打开

wangtong阅读(161)

第一种方法就是:

function is_weixin() {
    var ua = navigator.userAgent.toLowerCase(); 
    // alert(/Android|webOS|iPhone|iPod|BlackBerry/i.test(ua),"uauauaua")
     if (ua.match(/MicroMessenger/i) == "micromessenger" && /Android|webOS|iPhone|iPod|BlackBerry/i.test(ua)) { 
        return true; 
    }else { 
        // return true; 
        document.head.innerHTML = '<title>抱歉,出错了</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"><link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/0.4.1/weui.css">'; 
        document.body.innerHTML = '<div class="weui_msg"><div class="weui_icon_area"><i class="weui_icon_info weui_icon_msg"></i></div><div class="weui_text_area"><h4 class="weui_msg_title">请在手机端微信中打开链接</h4></div></div>'; 
    } 
}

第二种方法:

function is_weixin() { 
    var ua = navigator.userAgent.toLowerCase(); 
    var isWeChat = ua.match(/MicroMessenger/i) == "micromessenger"; 
    var isIpad = ua.match(/ipad/i) == "ipad"; 
    var isIphoneOs = ua.match(/iphone os/i) == "iphone os"; 
    var isMidp = ua.match(/midp/i) == "midp"; 
    var isUc7 = ua.match(/rv:1.2.3.4/i) == "rv:1.2.3.4"; 
    var isUc = ua.match(/ucweb/i) == "ucweb"; 
    var isAndroid = ua.match(/android/i) == "android"; 
    var isCE = ua.match(/windows ce/i) == "windows ce"; 
    var isWM = ua.match(/windows mobile/i) == "windows mobile"; 
    if (!(isWeChat || isIpad || isIphoneOs || isMidp || isUc7 || isUc || isAndroid || isCE || isWM) ){ 
        document.head.innerHTML = '<title>抱歉,出错了</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"><link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/0.4.1/weui.css">'; 
        document.body.innerHTML = '<div class="weui_msg"><div class="weui_icon_area"><i class="weui_icon_info weui_icon_msg"></i></div><div class="weui_text_area"><h4 class="weui_msg_title">请在手机端微信中打开链接</h4></div></div>'; 
    }else{ 
        return true; 
    } 
}

欢迎大家关注公众号:

 

【收藏】js数组方法整理

wangtong阅读(1212)

整理了以下数组方法

  • join()
  • push()和pop()
  • shift() 和 unshift()
  • sort()
  • reverse()
  • concat()
  • slice()
  • splice()
  • indexOf()和 lastIndexOf() (ES5新增)
  • forEach() (ES5新增)
  • map() (ES5新增)
  • filter() (ES5新增)
  • every() (ES5新增)
  • some() (ES5新增)

1、join()

join,就是把数组转换成字符串,然后给他规定个连接字符,默认的是逗号(  ,)

书写格式:join(” “),括号里面写字符串  (“要加引号”),

var arr = [1,2,3]; 
console.log(arr.join());     // 1,2,3 
console.log(arr.join("-"));   // 1-2-3 
console.log(arr);         // [1, 2, 3](原数组不变)

 

2、push()和pop()

push():  把里面的内容添加到数组末尾,并返回修改后的长度。

pop():移除数组最后一项,返回移除的那个值,减少数组的length。

书写格式:arr.push(” “),括号里面写内容  (“字符串要加引号”),

书写格式:arr.pop( )

var arr = ["Lily","lucy","Tom"]; 
var count = arr.push("Jack","Sean"); 
console.log(count);           // 5 
console.log(arr);            // ["Lily", "lucy", "Tom", "Jack", "Sean"] 
var item = arr.pop(); 
console.log(item);            // Sean 
console.log(arr);            // ["Lily", "lucy", "Tom", "Jack"]

3、shift() 和 unshift()   (和上面的push,pop相反,针对第一项内容)

shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。

 

unshift:将参数添加到原数组开头,并返回数组的长度 。

    书写格式:arr.shift(” “),括号里面写内容  (“字符串要加引号”),

var arr = ["Lily","lucy","Tom"]; 
var count = arr.unshift("Jack","Sean"); 
console.log(count);               // 5 
console.log(arr);                //["Jack", "Sean", "Lily", "lucy", "Tom"] 
var item = arr.shift(); 
console.log(item);               // Jack 
console.log(arr);                // ["Sean", "Lily", "lucy", "Tom"]

4、sort()

sort():将数组里的项从小到大排序

书写格式:arr.sort( )

var arr1 = ["a", "d", "c", "b"]; 
console.log(arr1.sort());           // ["a", "b", "c", "d"]

sort()方法比较的是字符串,没有按照数值的大小对数字进行排序,要实现这一点,就必须使用一个排序函数

function sortNumber(a,b) {
   return a - b 
}
arr = [13, 24, 51, 3]; 
console.log(arr.sort());           // [13, 24, 3, 51]
console.log(arr.sort(sortNumber));     // [3, 13, 24, 51](数组被改变)

5、reverse()

reverse():反转数组项的顺序。

书写格式:arr.reverse( )

var arr = [13, 24, 51, 3]; 
console.log(arr.reverse());         //[3, 51, 24, 13] 
console.log(arr);               //[3, 51, 24, 13](原数组改变)

6、concat()

concat() :将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。

    书写格式:arr.concat(),括号里面写内容  (“字符串要加引号”),

var arr = [1,3,5,7]; 
var arrCopy = arr.concat(9,[11,13]); 
console.log(arrCopy);             //[1, 3, 5, 7, 9, 11, 13] 
console.log(arr);               // [1, 3, 5, 7](原数组未被修改)

7、slice()

slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。

    书写格式:arr.slice( 1 , 3  )

var arr = [1,3,5,7,9,11]; 
var arrCopy = arr.slice(1); 
var arrCopy2 = arr.slice(1,4); 
var arrCopy3 = arr.slice(1,-2); 
var arrCopy4 = arr.slice(-4,-1); 
console.log(arr);               //[1, 3, 5, 7, 9, 11](原数组没变) 
console.log(arrCopy);             //[3, 5, 7, 9, 11] 
console.log(arrCopy2);            //[3, 5, 7] 
console.log(arrCopy3);            //[3, 5, 7] 
console.log(arrCopy4);            //[5, 7, 9]

arrCopy只设置了一个参数,也就是起始下标为1,所以返回的数组为下标1(包括下标1)开始到数组最后。

arrCopy2设置了两个参数,返回起始下标(包括1)开始到终止下标(不包括4)的子数组。

arrCopy3设置了两个参数,终止下标为负数,当出现负数时,将负数加上数组长度的值(6)来替换该位置的数,因此就是从1开始到4(不包括)的子数组。

arrCopy4中两个参数都是负数,所以都加上数组长度6转换成正数,因此相当于slice(2,5)。

8、splice()

splice():删除、插入和替换。

删除:指定 2 个参数:要删除的第一项的位置和要删除的项数。

书写格式:arr.splice( 1 , 3  )

插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。

书写格式:arr.splice(  2,0,4,6  )
替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。

    书写格式:arr.splice(  2,0,4,6  )

var arr = [1,3,5,7,9,11]; 
var arrRemoved = arr.splice(0,2); 
console.log(arr);                //[5, 7, 9, 11] 
console.log(arrRemoved);            //[1, 3] 
var arrRemoved2 = arr.splice(2,0,4,6); 
console.log(arr);                // [5, 7, 4, 6, 9, 11] 
console.log(arrRemoved2);           // [] 
var arrRemoved3 = arr.splice(1,1,2,4); 
console.log(arr);                // [5, 2, 4, 4, 6, 9, 11] 
console.log(arrRemoved3);           //[7]

9、indexOf()和 lastIndexOf()

indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。

    书写格式:arr.indexof( 5 )

lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。 

    书写格式:arr.lastIndexOf(  5,4  )

var arr = [1,3,5,7,7,5,3,1]; 
console.log(arr.indexOf(5));       //2 
console.log(arr.lastIndexOf(5));     //5 
console.log(arr.indexOf(5,2));      //2 
console.log(arr.lastIndexOf(5,4));   //2 
console.log(arr.indexOf("5"));      //-1

10、forEach()

forEach():对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是function类型,默认有传参,参数分别为:遍历的数组内容;第对应的数组索引,数组本身。

    书写格式:arr.forEach()

var arr = [1, 2, 3, 4, 5]; 
arr.forEach(function(x, index, a){ 
    console.log(x + '|' + index + '|' + (a === arr));
 });
 // 输出为: 
// 1|0|true 
// 2|1|true 
// 3|2|true 
// 4|3|true 
// 5|4|true

11、map()

map():指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。

    书写格式:arr.map()

var arr = [1, 2, 3, 4, 5]; 
var arr2 = arr.map(function(item){ 
    return item*item; 
}); 
console.log(arr2);         //[1, 4, 9, 16, 25]

12、filter()

filter():“过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。

    书写格式:arr.filter()

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
var arr2 = arr.filter(function(x, index) { 
    return index % 3 === 0 || x >= 8; 
}); 
console.log(arr2);         //[1, 4, 7, 8, 9, 10]

13、every()

every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。

    书写格式:arr.every()

var arr = [1, 2, 3, 4, 5]; 
var arr2 = arr.every(function(x) { 
    return x < 10; 
}); 
console.log(arr2);         //true 
var arr3 = arr.every(function(x) { 
    return x < 3; 
}); 
console.log(arr3);         // false

14、some()

some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。

    书写格式:arr.some()

var arr = [1, 2, 3, 4, 5]; 
var arr2 = arr.some(function(x) { 
    return x < 3; 
}); 
console.log(arr2);         //true 
var arr3 = arr.some(function(x) { 
    return x < 1; 
}); 
console.log(arr3);         // false

 

本文作者张永峰
本文链接:https://www.cnblogs.com/zyfeng/p/10541133.html

学习笔记4-React技术全家桶-组件实例的三大核心属性

wangtong阅读(467)

1、state

理解

  1. state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)

  1. 组件被称为”状态机”, 通过更新组件的state来更新对应的页面显示(重新渲染组件)

强烈建议:

  1. 组件中render方法中的this为组件实例对象

  1. 组件自定义的方法中this为undefined,如何解决?

    a) 强制绑定this: 通过函数对象的bind()

    b) 箭头函数

  2. 状态数据,不能直接修改或更新,必须是通过setState进行更新,且更新是一种合并不是替换

2、props

理解

  1. 每个组件对象都会有props(properties的简写)属性

  2. 组件标签的所有属性都保存在props中

作用

  1. 通过标签属性从组件外向组件内传递变化的数据

  2. 注意: 组件内部不要修改props数据

编码操作

  1. 内部读取某个属性值

    this.props.name

  2. 对props中的属性值进行类型限制和必要性限制

    第一种方式(React v15.5 开始已弃用):

    Person.propTypes = {
     name: React.PropTypes.string.isRequired,
     age: React.PropTypes.number
    }

    第二种方式(新):使用prop-types库进限制(需要引入prop-types库)

    Person.propTypes = {
      name: PropTypes.string.isRequired,
      age: PropTypes.number. 
    }

  3. 扩展属性: 将对象的所有属性通过props传递

    <Person {...person}/>

  4. 默认属性值:

    Person.defaultProps = {
      age: 18,
      sex:'男'
    }

  5. 组件类的构造函数

    constructor(props){
      super(props)
      console.log(props)//打印所有属性
    }

3、refs

理解

组件内的标签可以定义ref属性来标识自己

编码

  1. 字符串形式的ref

    <input ref="input1"/>

  1. 回调形式的ref

    <input ref={(c)=>{this.input1 = c}}

  2. createRef创建ref容器·

    myRef = React.createRef() 
    <input ref={this.myRef}/>

事件处理

  1. 通过onXxx属性指定事件处理函数(注意大小写)

    1) React使用的是自定义(合成)事件, 而不是使用的原生DOM事件

    2) React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)

  1. 通过event.target得到发生事件的DOM元素对象

 

 

 

欢迎大家关注公众号:

学习笔记3-React技术全家桶-组件

wangtong阅读(412)

## 模块与组件、模块化与组件化的理解
### 模块:
​   理解:向外提供特定功能的js程序(一个js文件就是一个模块)
​   为什么要拆成模块:业务量增加的话,代码会越来越多,并且变得更加复杂,维护成本会提高
​   作用:将js变更为可复用的文件,简化js的编写及提高js的运行效率
### 组件
​   理解:用来实现局部功能效果的代码和资源的集合(html、js、css、image等)
​   为什么要用组件:一个页面的功能更加复杂
​   作用:服用编码,简化项目编码,提高运行效率
### 模块化
​   当应用的js都以模块来编写的, 这个应用就是一个模块化的应用
### 组件化
​   当应用是以多组件的方式实现, 这个应用就是一个组件化的应用
## React 面向组件编程
### 组件的定义方式:
    1、函数式组件
        执行了ReactDOM.render(<MyComponent/>,document.getElementById(‘test’))之后,发生了什么:
                1、React解析组件标签,找到了<MyComponent/>组件
                2、发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,之后呈现在页面中。
    2、类式组件
        执行了ReactDOM.render(<MyComponent/>,document.getElementById(‘test’))之后,发生了什么:
                1、React解析组件标签,找到了<MyComponent/>组件
                2、发现组件是使用类定义的,随后new 出该类的实例,并通过该实例调用到原型上的render方法。
                3将render返回的虚拟DOM转为真实DOM,之后呈现在页面中。
        类的基本知识复习:
             总结:
             1、类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写
             2、如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须要调用的
             3、类中所定义的方法,都是放在类的原型对象上,供实例去使用
### 注意
    1、组件名必须首字母大写
    2、虚拟DOM元素只能有一个根元素
    3、虚拟DOM元素必须有结束标签
### 渲染类组件标签的基本流程:
    1、React内部会创建组件实例对象
    2、调用render()得到的虚拟DOM,并解析为真实DOM
    3、插入到指定的页面元素内部

欢迎大家关注公众号:

学习笔记2-React技术全家桶

wangtong阅读(414)

## 基本使用
    1、核心js库:
        (1)react.js:React核心库。
        (2)react-dom.js:提供操作DOM的react扩展库。
        (3)babel.min.js:解析JSX语法代码转为JS代码的库。
    2、创建虚拟DOM的两种方式:
        (1)纯JS创建
        (2)JSX创建
## JSX语法规则:
    1、定义虚拟DOM时,不要写引号
    2、标签中混入JS表达式时要用{}
        一定注意区分:【js语句(代码)】与【js表达式】
            1、表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
                下面这些都是表达式:
                    (1)a
                    (2)a+b
                    (3)demo(1)
                    (4)arr.map()
                    (5)funuction test(){}
            2、语句(代码):
                下面这些都是语句(代码):
                    (1)if(){}
                    (2)for(){}
                    (3)switch(){case:***}
    3、样式的类名指定不能用class,要用className
    4、内联样式格式:style={{key:value}}
    5、虚拟DOM只能有一个根标签
    6、标签必须闭合
    7、标签首字母
        (1)若小写字母开头,则将改标签为html中同名元素,若html中无该标签对应的同名元素,则报错
        (2)若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。

欢迎大家关注公众号:

【收藏】JS中Class类的详解

wangtong阅读(540)

概述

在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类。它可以被看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。
类实际上是个“特殊的函数”,就像你能够定义的函数表达式和函数声明一样,类语法有两个组成部分:类表达式和类声明。

严格模式

类和模块的内部,默认就是严格模式,所以不需要使用 use strict 指定运行模式

类的声明

定义一个类的一种方法是使用一个类声明,即用带有class关键字的类名(这里是“Rectangle”)
函数名和实例化构造名相同且大写(非强制)

class Person {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
}

函数声明和类声明之间的一个重要区别是函数声明会提升,类声明不会。需要先进行声明,再去访问,否则会报错

var person= new Person()
class Person {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
}
// Personis not defined

类声明不可以重复

class Person {}
class Person {}
// TypeError Identifier 'Person' has already been declared

类必须使用 new 调用,否则会报错。这是它跟普通构造函数的一个主要区别,就是后者不用 new 也可以执行

class Person {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
}
Person()
// TypeError Class constructor Person cannot be invoked without 'new'

类表达式(类定义)

类表达式可以是被命名的或匿名的

/* 匿名类 */ 
let Person = class {
        constructor(x, y) {
        this.x = x
        this.y = y
    }
}

/* 命名的类 */ 
let Person = class Person {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
}

类的方法
constructor 方法

constructor 方法是类的默认方法,通过 new 命令生成对象实例时,自动调用该方法(默认返回实例对象 this)。一个类必须有 constructor 方法,如果没有显式定义,一个空的 constructor 方法会被默认添加。一个类只能拥有一个名为 “constructor” 的特殊方法,如果类包含多个 constructor 的方法,则将抛出 一个 SyntaxError 。

class Person {
    constructor(x, y) {
        this.x = x // 默认返回实例对象 this
        this.y = y
    }
    toString() {
        console.log(this.x + ', ' + this.y)
    }
}

注意:

  1. 在类中声明方法的时候,方法前不加 function 关键字
  2. 方法之间不要用逗号分隔,否则会报错
  3. 类的内部所有定义的方法,都是不可枚举的(non-enumerable)
  4. 一个类中只能拥有一个 constructor 方法

静态方法

静态方法可以通过类名调用,不能通过实例对象调用,否则会报错

class Person {
    static sum(a, b) {
        console.log(a + b)
    }
}
var p = new Person()
Person.sum(1, 2) // 3
p.sum(1,2) // TypeError p.sum is not a function

原型方法

类的所有方法都定义在类的 prototype 属性上面,在类的实例上面调用方法,其实就是调用原型上的方法
原型方法可以通过实例对象调用,但不能通过类名调用,会报错

class Person {
    constructor() {
        // 默认返回实例对象 this
    }
    sum() {
    }
    toString() {
        console.log('123456')
    }
}
// 给 Person 的原型添加方法
Person.prototype.toVal = function() {
    console.log('I am is toVal')
}

// 等同于
Person.prototype = {
    constructor() {},
    sum() {},
    toString() {}
}

var p = new Person()
p.toString() // 123456
p.toVal() // I am is toVal
Person.toString() // TypeError Person.toStringis not a function
Person.toVal() // TypeError Person.toVal is not a function

实例方法

实例方法也可以通过实例对象调用,但同样不能通过类名调用,会报错

class Person {
    constructor() {
        this.sum = function(a, b) {
            console.log(a + b)
        }
    }
}
var p = new Person()
p.sum(1,2) // 3
Person.sum(1,2) // TypeError Person.sum is not a function

欢迎大家关注公众号:

 

 

————————————————
版权声明:本文为CSDN博主「半度℃温热」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fu983531588/article/details/89499461