【前端从0开始】JavaSript——自定义函数
函数
- 函数是一个可重用的代码块,用来完成某个特定功能。每当需要反复执行一段代码时,可以利用函数来避免重复书写相同代码。
- 函数包含着的代码只能在函数被调用时才会执行,就可以避免页面载入时执行该脚本
- 在JavaScript中,可以使用以下三种方法来定义一个函数
- 使用function语句定义函数
- 使用Function()构造函数来定义函数
- 在表达式中定义函数
Function构造函数定义函数
var 函数名 = new Function(“参数1”,”参数2”,”参数3”……”函数体”);
注意:
1. 在使用Function()构造函数的时候,第一个字母要大写
2. Function()构造函数只能在JavaScript 1.1或更高版本中使用
3. 每次调用构造函数时都会解析函数体,并且创建一个新的函数对象,效率非常底
function语句定义函数
function 函数名 (参数1,参数2……[形参]){<语句块>return 返回值
}
function关键字:用于定义一个函数
函数名:函数名通常是一个合法的标识符,是唯一的,区分大小写的
参数:在函数里,可以有0个或者多个参数。如果有多个参数,参数与参数之间要用逗号隔开。无论函数是否有参数,小括号必需要有
函数体:用大括号括起来的代码块,即函数的主体
返回值:函数返回的值由关键字return完成,可选项
在表达式中直接定义函数
var 函数名 = function (参数1,参数2,…){函数体};
注意:
在表达式中定义函数的方法只能在JS1.2版本或以上版本中使用
函数名()
函数名/变量名
var rightKey=function(){if(event.button==2){alert("禁止使用鼠标右键");}
}
window.onmousedown = rightKey;
调用函数
1.直接调用
myFunction();或window.myFunction()
2.事件处理中调用
<div onclick="myFunction()"></div>
3.将函数的返回值赋给变量
var t = myFunction();
函数的参数
形參:定义函数时,函数名后面()中的参数;JavaScript中的函数允许给行参赋初始值
实参:调用函数时,传递的参数
参数的匹配:
默认情况下,形參和实参是一一对应的
但是当传递的参数个数与函数定义好的参数个数可以不匹配当不匹配时
- 如果传递的参数个数小于函数定义的参数个数,JavaScript会自动将多余的参数值设为undefined;
- 如果传递的参数个数大于函数定义的参数个数,那么多余传递的参数将会被忽略掉。
获取所有实参【arguments】
function Test(a,b){alert(typeof(arguments)); // 获得类型alert(arguments[1]); // 获取下标为1的参数值alert(arguments.length); // 获取参数的长度alert(arguments.callee); // 获取函数的所有内容
}
Test("zhang","li");
默认参数
JavaScript中的函数允许给参数赋初始值
比如:我们在创建封装一个创建table表格的函数,如果任何参数不传,我们也想创建一个四行五列,并且背景颜色,各行换色的表格,这时候我们就可以使用表格来创建
案例:创建一个带默认参数的函数
function tab(row,color='pink',color2='gray'){document.write('<table border="1" width="500">');for(var index = 0; index < row; index++){if(index%2 == 1){document.write('<tr bgcolor="'+color+'"><td>'+index +'</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>');}else{document.write('<tr bgcolor="'+color2+'"><td>'+index +'</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>');}}document.write('</table>');
}
tab(10,'gray','orange');
函数的返回值
●return语句并不是必须的
●默认情况下,函数的返回值为undefined
●在使用 return 语句时,函数会停止执行,并返回指定的值,return后面的代码不再执行
什么情况下添加return:
如果函数中的变量要在函数外进行调用
函数体的结果需要在函数外进行使用
变量的作用域
全局变量:
在函数外声明的的变量为全局,在整个JS文档中生效
局部变量:
在函数内用var声明的变量为局部变量,只能在函数内部使用。
全局变局部
全局变量可以在局部的任意位置使用
局部变全局
局部变量不能在全局使用,如果想要在全局使用,可以去除前边的var或者将该值使用return返回到全局
块级作用域【ES6中新增的内容】
什么是作用域链【了解】
●只要在js中创建变量,就会存在作用域【全局作用域】
●写在函数内部的被称为局部作用域
●如果函数中还有函数,那么在这个作用域中就又可以诞生一个新的作用域
●在函数中如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这样一个查找过程形成的链条就叫做作用域链。
默认情况下:内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境的任何变量和函数
var n = 10;
function outer(){function inner(){function center(){console.log(n);}center();}inner();var n = 15;
}
outer(); //=> undefined
案例:案例分析
var a = 1
function fn1(){function fn2(){console.log(a)}function fn3(){var a = 4fn2()}var a = 2return fn3
}
var fn = fn1()
fn() //输出多少?
如函数的执行,形成一个私有作用域,形参和当前私有作用域中声明的变量都是私有变量,保存在内部的一个变量对象中,其下一个外部环境可能是函数,也就包含了函数的内部变量对象,直到全局作用域。
预解析
预解析,又称之为变量提升,在js代码真正执行之前,进行提前加载,把所有带有var和function的关键字进行预解析
●JavaScipt代码是由浏览器中的JavaScript解析器来执行的
●JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行
●预解析分为变量预解析(变量提升)和函数预解析(函数提升)
●代码执行是按代码的书写顺序从上到下执行的
- 对于带有var和function关键字在预解释的时候操作
var :只声明不定义
function:既声明又定义
注:私有作用域下也要进行预解析 - 预解析只发生在当前的作用域下
就是当文档加载的时候,开始只对window进行预解析,函数执行的时候才会对里面的代码进行预解析
console.log(a); // 注意:预解析的问题,如果同时有变量和函数的预解析,那么函数的优先级高
var a = 'hello';
function a(){console.log(123);
}// 优先执行栈内存中的内容
// function a(){
// console.log(123);
// }
// var a = 'hello';
// console.log(a); // hello
案例:分析代码结果
// 案例1
var num = 10;
fun();
function fun(){console.log(num);var num = 20;
}
// 案例二
var num = 10;
function fun() {console.log(num);var num = 20;console.log(num);
}
fun();// 案例三
var a = 18;
f1();
function f1() {var b = 9;console.log(a);console.log(b);var a = 13;
}// 案例四
console.log(a,b,c);
var a = b = c = 5;// 案例四
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {var a = b = c = 9;console.log(a);console.log(b);console.log(c);
}
// 案例五
fn();//报错 只预解析“=”左边的,右边的是指针,不参与预解析
var fn=function(){console.log(11);
}
// 案例六
function fn(){console.log(a);a=100;
}
fn();
console.log(a);
//注意:js中,如果在不进行任何特殊处理的情况下,上面的代码报错,下面的代码不再执行// 案例七
console.log(show);
function show(){console.log(123);
}
var show = 10;// 案例八
function show(){console.log(123);
}
var show = 10;
console.log(show);
案例:分析代码结果
// 案例1
var num = 10;
fun();
function fun(){console.log(num);var num = 20;
}
// 案例二
var num = 10;
function fun() {console.log(num);var num = 20;console.log(num);
}
fun();// 案例三
var a = 18;
f1();
function f1() {var b = 9;console.log(a);console.log(b);var a = 13;
}// 案例四
console.log(a,b,c);
var a = b = c = 5;// 案例四
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {var a = b = c = 9;console.log(a);console.log(b);console.log(c);
}
// 案例五
fn();//报错 只预解析“=”左边的,右边的是指针,不参与预解析
var fn=function(){console.log(11);
}
// 案例六
function fn(){console.log(a);a=100;
}
fn();
console.log(a);
//注意:js中,如果在不进行任何特殊处理的情况下,上面的代码报错,下面的代码不再执行// 案例七
console.log(show);
function show(){console.log(123);
}
var show = 10;// 案例八
function show(){console.log(123);
}
var show = 10;
console.log(show);
变量的生命周期【了解】
JavaScript 变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>
</ul>var lis = document.getElementsByTagName("li");for(var i=0; i<lis.length;i++){lis[i].onclick = function(){alert(i);}
}
案例:
// 案例一
function test(){uname = "香水有毒";
}
console.log(uname);// 案例二
function test(){uname = "香水有毒";
}
test();
console.log(uname); // 案例三
uname = "香水有毒";
function test(){console.log(uname);
}
test(); // 案例四
var uname = "香水有毒";
function test(){console.log(uname);
}
function test2(){uname = "老鼠爱大米";test();
}
test2(); // 案例五
var uname = "香水有毒";
function test(){console.log(uname);
}
function test2(){uname = "老鼠爱大米";return test;
}
res=test2();
res();
自执行函数
(function a(){alert('我是自执行函数')} ()); // 用括号把整个表达式包起来
(function a(){alert('我是自执行函数')}) (); //用括号把函数包起来
!function a(){alert('我是自执行函数')}(); // 求反,我们不在意值是多少,只想通过语法检查。
+function a(){alert('我是自执行函数')}();
-function a(){alert('我是自执行函数')}();
~function a(){alert('我是自执行函数')}();
void function a(){alert('我是自执行函数')}();
new function a(){alert('我是自执行函数')}();
自执行函数通常都是定义之后立即执行,以后都不再会调用,所以声明时可以省略函数名,因此自执行函数又叫匿名函数 。
(function(){console.log('我是匿名函数')})();// 我是匿名函数
如果上一行代码没有使用 分号 ’ ; '结束,可能会导致匿名函数通不过语法检查,所以通常会在小括号前加个分号
;(function(){console.log('我是匿名函数')})()// 我是匿名函数
自执行函数的效果
自执行函数可以用来保存变量的作用域,防止污染全局变量
以一个经典的面试题为例;
<ul><li>这是第1个li</li><li>这是第2个li</li><li>这是第3个li</li><li>这是第4个li</li><li>这是第5个li</li><li>这是第6个li</li>
</ul>
一个列表里有6个li,要求点击li的时候打印当前被点击li的索引。
如果我们直接通过for循环绑定事件:
var lis = document.querySelectorAll('li');
for(var i = 0;i<lis.length;i++){lis[i].onclick = function (){console.log(i)}
}
// 无论哪个li被点击,打印的永远都是相同的值,因为在所有的点击事件中,访问的都是全局的 i,当事件触发时,i的值已经变成是lis.length了。
在es6语法出现之后,我们使用 let 关键字创建的块级作用域可以解决这种问题,在 let 出现以前,通常是使用匿名函数+闭包的方式创建函数作用域来保存每一步循环里 i 的值;
var lis = document.querySelectorAll('li');
for(var i = 0;i<lis.length;i++){(function(i){lis[i].onclick = function (){console.log(i)}})(i)
}
// 使用这种方法,每次循环都会创建一个匿名函数,这个匿名函数生成了闭包的效果,新建了一个作用域,
// 这个作用域接收到每次循环的i值保存了下来,即使循环结束,闭包形成的作用域也不会被销毁;
// 事件处理函数中访问的 i 不再是全局变量,而且匿名函数中的局部变量。
闭包
什么是闭包:闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
特点:
- 闭包就是一个特殊的函数
- 函数内部可以引用函数外部的参数和变量【能访问到其他作用域中的变量】
- 参数和变量不会被垃圾回收机制回收【延长变量的生命周期】
创建闭包
// 简单的闭包,
var num = 10;
function show(){console.log(num);
}// 局部变量在全局使用
function show(){var num = 10;return function(){ // 闭包函数return num};
}
var b = show();
console.log(b());// 局部变量
function f1(){var n=999;
}// 局部变量在全局使用
function f1(){var n=999;function f2(){ alert(n); // 999}return f2; // 闭包函数
}
f1()()// 总结:闭包就是能够读取其他函数内部变量的函数。
案例:将普通函数改为闭包函数
// 普通函数
function show(){var m = 1;function inner(){var n = 0;console.log(++n);console.log(++m);};inner();
}// 闭包函数
function show(){var m = 1;return function(){var n = 0;console.log(++n);console.log(++m);};
}
闭包的用途:
- 是前面提到的可以读取函数内部的变量
- 就是让这些变量的值始终保持在内存中。
闭包的缺点
比普通函数更占用内存,会导致网页性能变差,在IE下容易造成内存泄露。
什么是内存泄漏
首先,需要了解浏览器自身的内存回收机制。
每个浏览器会有自己的一套回收机制,当分配出去的内存不使用的时候便会回收;内存泄露的根本原因就是你的代码中分配了一些‘顽固的’内存,浏览器无法进行回收,如果这些’顽固的’内存还在一直不停地分配就会导致后面所用内存不足,造成泄露。
闭包造成内存泄漏
因为闭包就是能够访问外部函数变量的一个函数,而函数是必须保存在内存中的对象,所以位于函数执行上下文中的所有变量也需要保存在内存中,这样就不会被回收,如果一旦循环引用或创建闭包,就会占据大量内存,可能会引起内存泄漏
函数案例
- 封装一个反转数组方法
// 方法一
function reverse(arr){var newArr = [];for(var i=0;i<arr.length;i++){newArr[arr.length-i-1] = arr[i];}return newArr;
}
var arr1 = reverse([1,4,7,9,12,16]);
console.log(arr1);// 方法二
function reverse(arr){var newArr = [];for(var i=arr.length-1;i>=0;i--){newArr[newArr.length] = arr[i]} return newArr;
}
var arr1 = reverse([1,4,7,9,12,16]);
console.log(arr1);// 注意:数组中不管是任意内容,都可以实现反转
- 函数封装实现 - 冒泡排序
function sort(arr){for(var i=0;i<arr.length-1;i++){for(var j=0;j<arr.length-i-1;j++){if(arr[j] > arr[j+1]){var temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;} }}return arr;
}
var arr1 = sort([40,8,15,18,12]);
console.log(arr1);
- 使用函数,判断今年是平年还是闰年
function isRunYear(year){// 闰年 true,平年 falsevar flag = false;if((year%4==0 && year %100!=0 )||year%400==0){flag = true;}return flag;
}
console.log(isRunYear(2000));
// 思考:输入年份,判断当前年份的2月份有多少天
- 获取数组中的最大值
function max(arr){var max = arr[1];for(var i=0;i<arr.length;i++){if(arr[i] > max){max = arr[i]}}return max;
}
console.log(max([1,34,96,23,78]));
相关文章:

【前端从0开始】JavaSript——自定义函数
函数 函数是一个可重用的代码块,用来完成某个特定功能。每当需要反复执行一段代码时,可以利用函数来避免重复书写相同代码。函数包含着的代码只能在函数被调用时才会执行,就可以避免页面载入时执行该脚本在JavaScript中,可以使用…...

如何在Windows、Mac和Linux操作系统上安装Protocol Buffers(protobuf)编译器
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

简单介绍 CPU 的工作原理
内部架构 CPU 的根本任务就是执行指令,对计算机来说最终都是一串由 0 和 1 组成的序列。CPU 从逻辑上可以划分成 3 个模块,分别是控制单元、运算单元和存储单元 。其内部架构如下: 【1】控制单元 控制单元是整个CPU的指挥控制中心ÿ…...

UE4/5数字人MetaHuman的控制绑定资产使用
目录 开始操作 找到控制绑定资产 放入控制绑定资产 编辑 生成动画资产 开始操作 首先我们创建一个关卡序列: 打开后将我们的数字人放进去【右键,第一个添加进去】: 我们会自动进入动画模式,没有的话,就自己…...

二、11.系统交互
fork 函数原型是 pid_t fork(void),返回值是数字,该数字有可能是子进程的 pid ,有可能是 0,也有可能是-1 。 1个函数有 3 种返回值,这是为什么呢?可能的原因是 Linux 中没有获取子进程 pid 的方…...
敏捷管理工具/国内软件敏捷开发工具
Scrum中非常强调公开、透明、直接有效的沟通,这也是“可视化的管理工具”在敏捷开发中如此重要的原因之一。通过“可视化的管理工具”让所有人直观的看到需求,故事,任务之间的流转状态,可以使团队成员更加快速适应敏捷开发流程。…...

Selenium环境+元素定位大法
selenium 与 webdriver Selenium 是一个用于 Web 测试的工具,测试运行在浏览器中,就像真正的用户在手工操作一样。支持所有主流浏览器 WebDriver 就是对浏览器提供的原生API进行封装,使其成为一套更加面向对象的Selenium WebDriver API。 使…...

Vue3 用父子组件通信实现页面页签功能
一、大概流程 二、用到的Vue3知识 1、组件通信 (1)父给子 在vue3中父组件给子组件传值用到绑定和props 因为页签的数组要放在父页面中, data(){return {tabs: []}}, 所以顶部栏需要向父页面获取页签数组 先在页签页面中定义props用来接…...
HCIP STP协议
STP协议 STP协议概念生成树为什么要用STP STP名词解释根网桥根端口指定端口非指定端口 STP的版本802.1DPVSTPVST 快速生成树 STP协议概念 IEEE 802.1d STP(生成树协议,Spanning-Tree Protocol)协议: ①使冗余端口置于“阻塞状态”…...

链表的顶级理解
目录 1.链表的概念及结构 2.链表的分类 单向或者双向 带头或者不带头 循环或者非循环 3.无头单向非循环链表的实现 3.1创建单链表 3.2遍历链表 3.3得到单链表的长度 3.4查找是否包含关键字 3.5头插法 3.6尾插法 3.7任意位置插入 3.8删除第一次出现关键字为key的节点 …...
探索贪心算法:理解与实现JAVA语言
探索贪心算法:理解与实现 贪心算法(Greedy Algorithm)是一种基于每一步的最优选择来达到整体最优的算法思想。尽管贪心算法并不适用于所有问题,但它在很多情况下都能够提供高效、近似的解决方案。本文将深入探讨贪心算法的基本概…...

数字孪生技术对旅游行业能起到什么作用?
随着疫情对我们生活影响的淡化,旅游行业迎来了新的春天,暑期更是旅游行业的小高潮,那么作为一个钻研数字孪生行业的小白,本文就着旅游的话题以及对旅游的渴望带大家一起探讨一下数字孪生对智慧旅游发展的作用~ 数字孪生作为一种虚…...

攻防世界-Web_php_include
原题 解题思路 php://被替换了,但是只做了一次比对,改大小写就可以绕过。 用burp抓包,看看有哪些文件 flag明显在第一个PHP文件里,直接看...

Python Opencv实践 - 直方图显示
import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) print(img.shape)#图像直方图计算 #cv.calcHist(images, channels, mask, histSize, ranges, hist, accumulate) #images&…...

2分钟搭建自己的GPT网站
如果觉得官方免费的gpt(3.5)体验比较差,总是断开,或者不会fanqiang,那你可以自己搭建一个。但前提是你得有gpt apikey。年初注册的还有18美金的额度,4.1号后注册的就没有额度了。不过也可以自己充值。 有了…...
deepdiff比较两个json文件数据差异性
deepdiff比较两个json文件数据差异性 Python代码片: import json import sysfrom deepdiff import DeepDiff from deepdiff import grep, DeepSearch from deepdiff import DeepHash# print(DeepDiff("abc", "abcd", ignore_orderTrue))class …...

文件内容搜索工具 - Python实现
在本篇文章中,我们将介绍如何使用 wxPython 库创建一个简单的文件搜索工具。这个工具允许用户选择一个文件夹,并在该文件夹中的所有 .py 文件中查找指定的文字,并显示匹配的位置。 C:\pythoncode\blog\searchwordinpyfile.py 代码实现 我们首…...
vue静态html加载外部组件
当我们在开发vue应用时, 使用的是html页面开发, 需要引用外部vue组件, 怎么办呢, 首先我们引用http-vue-loader.js文件, 像下面这样: <script src"/assets/javascript/vue.min.js"></script> <script src"/assets/javascript/http-vue-loader.j…...
WebSocket 中的心跳是什么,有什么作用?
在网络应用开发中,WebSocket 是一种重要的通信协议,它允许客户端和服务器之间建立持久性的双向通信连接。然而,为了保持连接的稳定性,WebSocket 中的心跳是一个不可或缺的概念。本文将详细介绍 WebSocket 中的心跳是什么ÿ…...

Android类加载机制
要说Android的类加载机制 ,就离不开 类加载器ClassLoader,它是一个抽象接口 下面这个图还是比较好表达了类加载流程,但如果不看我红色画的线,就会感觉有点乱,需要注意是采用的是双亲委派模式,class加载要先…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...